
- 1.邻接表 深搜 暴力做法
- 1.1问1
- 1.1.1c++
- 1.1.2Java
- 1.2问2
- 1.2.1c++
- 1.2.2Java
下图是为了解释DFS()函数中的color[v] = 0语句;
题目:
输入无向图的_case个数,指定每个图的顶点个数N,边数E,图着色的颜色数量M,
以及边的具体情况.
问1:图中相连的点不是同色的.有多少中可能.
或
输入无向图的个数,指定每个图的顶点个数N,边数E,以及边的具体情况.
问2:图中相连的点不是同色的,至少要多少种颜色,并输出所有结果.
#include1.1.2Java#include #include #include using namespace std; int _case; // 图数,边的起点,终点 int N, E, M; // 顶点数,边数和颜色数; vector > Graph; // 存放图的结构; vector color; // 所图的颜色 int resCnt = 0; // 结果的总数 bool ok(int k) { for (int j = 1; j <= N; j++) if (Graph[j][k] == 1 && color[k] == color[j]) return false; // 点j与点k相连,且同色返回false return true; // 有两种可能: // ①点k与其他点都不相连,说明这个颜色可以图 // ②相连但不同色,说明这个颜色可以图 // 于是就可以涂下一个点的颜色 } void DFS(int v) { if (v > N) { //满足条件说明前N个顶点都确定了颜色 for (int i = 1; i <= N; i++) //依次所有顶点涂的颜色 cout << color[i] << " "; resCnt++; //涂的方法数+1; cout << endl; return; } else { for (int i = 1; i <= M; i++) { //访问每一种涂法方法; color[v] = i; //涂上颜色; if (ok(v)) //返回true说明,满足涂色的规则; DFS(v + 1); //n那么就进行下一个顶点的涂色; color[v] = 0; //回溯,避免后面的点影响前面的点着色, } } } int main() { cin >> _case; while (_case--) { cin >> N >> E >> M; //顶点数,边数,颜色数 //防止上一个图的遗留数据影响到这个图 Graph.clear(); Graph.resize(N + 2); for (int k = 0; k < N + 2; ++k) { Graph[k].resize(N + 2); //每行为c列 } int a, b; while (E--) { //输入边 cin >> a >> b; Graph[a][b] = Graph[b][a] = 1; //1表示两个点相连 } resCnt = 0; //结果数 color.clear(); color.resize(N + 2); DFS(1); //从第一个顶点开始 cout << "Total=" << resCnt << endl << endl; } return 0; }
import java.util.Scanner;
public class Main{
static int _case, n, e, m;//图,点,边,颜色
static int[][] q;//邻接表存图结构
static int[] col;//结点涂色情况(什么色)
static int a, b, res;//边的起点,边的终点,涂色方案总数
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
System.out.println("请输入图的数量:");
_case = in.nextInt();
while (_case-- > 0) {
//点数,边数,颜色数
n = in.nextInt();
e = in.nextInt();
m = in.nextInt();
//根据上面数据设置邻接表大小
q = new int[n + 2][n + 2];
while (e-- > 0) {
//输入边
a = in.nextInt();
b = in.nextInt();
q[a][b] = q[b][a] = 1;
}
//同上
col = new int[n + 2];
res=0;
dfs(1);
System.out.println("一共有"+res+"种可能.");
}
}
private static void dfs(int v) {
if (v > n) {
res++;
for (int i = 1; i <= n; i++) {
System.out.print(col[i]);
System.out.print(' ');
}
System.out.println();
}else{
for (int i = 1; i <= m; i++) {
col[v]=i;
if(ok(v)){
dfs(v+1);
}
col[v]=0;
}
}
}
private static boolean ok(int v) {
for (int i = 1; i <=n ; i++) {
if(q[i][v]==1&&col[i]==col[v])return false;
}
return true;
}
}
1.2问2
1.2.1c++
#include1.2.2Java#include #include #include using namespace std; int _case; // 图数,边的起点,终点 int N, E, M; // 顶点数,边数和颜色数; vector > Graph; // 存放图的结构; vector color; // 所图的颜色 int resCnt = 0; // 结果的总数 bool ok(int k) { for (int j = 1; j <= N; j++) if (Graph[j][k] == 1 && color[k] == color[j]) return false; // 点j与点k相连,且同色返回false return true; // 有两种可能: // ①点k与其他点都不相连,说明这个颜色可以图 // ②相连但不同色,说明这个颜色可以图 // 于是就可以涂下一个点的颜色 } void DFS(int v) { if (v > N) { //满足条件说明前N个顶点都确定了颜色 for (int i = 1; i <= N; i++) //依次所有顶点涂的颜色 cout << color[i] << " "; resCnt++; //涂的方法数+1; cout << endl; return; } else { for (int i = 1; i <= M; i++) { //访问每一种涂法方法; color[v] = i; //涂上颜色; if (ok(v)) //返回true说明,满足涂色的规则; DFS(v + 1); //n那么就进行下一个顶点的涂色; color[v] = 0; //回溯,避免后面的点影响前面的点着色, } } } int main() { cin >> _case; while (_case--) { cin >> N >> E; //顶点数,边数,颜色数 M = 2; //防止上一个图的遗留数据影响到这个图 Graph.clear(); Graph.resize(N + 2); for (int k = 0; k < N + 2; ++k) { Graph[k].resize(N + 2); //每行为c列 } int a, b; while (E--) { //输入边 cin >> a >> b; Graph[a][b] = Graph[b][a] = 1; //1表示两个点相连 } while (true) { resCnt = 0; //结果数 color.clear(); color.resize(N + 2); DFS(1); //从第一个顶点开始 if (resCnt > 0) { cout << "至少要" << M << "种颜色" << endl; cout << "Total=" << resCnt << endl << endl; break; } M++; } } return 0; }
import java.util.Scanner;
public class Main {
static int _case, n, e, m;//图,点,边,颜色
static int[][] q;//邻接表存图结构
static int[] col;//结点涂色情况(什么色)
static int a, b, res;//边的起点,边的终点,涂色方案总数
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
System.out.println("请输入图的数量:");
_case = in.nextInt();
while (_case-- > 0) {
//点数,边数,颜色数
n = in.nextInt();
e = in.nextInt();
m = 2;
//根据上面数据设置邻接表大小
q = new int[n + 2][n + 2];
while (e-- > 0) {
//输入边
a = in.nextInt();
b = in.nextInt();
q[a][b] = q[b][a] = 1;
}
//同上
while (true) {
col = new int[n + 2];
res = 0;
dfs(1);
if (res > 0) {
System.out.println("至少"+m+"种颜色.");
System.out.println("一共有" + res + "种可能.");
break;
}
m++;
}
}
}
private static void dfs(int v) {
if (v > n) {
res++;
for (int i = 1; i <= n; i++) {
System.out.print(col[i]);
System.out.print(' ');
}
System.out.println();
} else {
for (int i = 1; i <= m; i++) {
col[v] = i;
if (ok(v)) {
dfs(v + 1);
}
col[v] = 0;
}
}
}
private static boolean ok(int v) {
for (int i = 1; i <= n; i++) {
if (q[i][v] == 1 && col[i] == col[v]) return false;
}
return true;
}
}
欢迎分享,转载请注明来源:内存溢出
微信扫一扫
支付宝扫一扫
评论列表(0条)