实验12图的m着色问题
问题:
给定无向连通图$G$和$m$种颜色,用这些颜色给图的顶点着色,每个顶点一种颜色。如果要求$G$的每条边的两个顶点着不同颜色。给出所有可能的着色方案;如果不存在,则回答$”NO”$。
解析:
对于每个点选择颜色$i$时判断其与所有相连的已着色的点是否发生颜色冲突,若未发生冲突,则$dfs$向后接着选择下一个点的颜色。如果所有的点都已着色,则输出着色方案。
设计(核心代码):
1 void dfs(int x) { 2 if (x > n) { 3 cout << ++ans << " : "; 4 for (int i = 1; i <= n; ++i) { 5 cout << vis[i] << " "; 6 } 7 cout << endl; 8 return; 9 } 10 for (int i = 1; i <= m; ++i) { 11 vis[x] = i; 12 if (check(x, i)) dfs(x + 1); 13 vis[x] = 0; 14 } 15 }
分析:
复杂度:$O(n*m^{n})$。
源码:
https://github.com/Big-Kelly/Algorithm
1 //#include<bits/stdc++.h> 2 #include<time.h> 3 #include <set> 4 #include <map> 5 #include <stack> 6 #include <cmath> 7 #include <queue> 8 #include <cstdio> 9 #include <string> 10 #include <vector> 11 #include <cstring> 12 #include <iostream> 13 #include <algorithm> 14 15 #define ll long long 16 #define pll pair<ll,ll> 17 #define pii pair<int,int> 18 #define bug printf("*********\n") 19 #define FIN freopen("input.txt","r",stdin); 20 #define FON freopen("output.txt","w+",stdout); 21 #define IO ios::sync_with_stdio(false),cin.tie(0) 22 #define ls root<<1 23 #define rs root<<1|1 24 #define pb push_back 25 #define PI acos(-1.0) 26 27 using namespace std; 28 const int inf = 0x3f3f3f3f; 29 const ll INF = 1e18 + 7; 30 const int maxn = 100 + 5; 31 const ll mod = 1e9 + 7; 32 const double eps = 1e-6; 33 34 inline ll read() { 35 bool f = 0; 36 ll x = 0; char ch = getchar(); 37 while (ch < '0' || ch>'9') { if (ch == '-')f = 1; ch = getchar(); } 38 while (ch >= '0' && ch <= '9') { x = (x << 3) + (x << 1) + (ch ^ 48); ch = getchar(); } 39 return f ? -x : x; 40 } 41 42 ll gcd(ll a, ll b) { 43 return b == 0 ? a : gcd(b, a % b); 44 } 45 46 int n, m, cnt; 47 int mp[maxn][maxn], vis[maxn], ans; 48 49 void init() { 50 memset(mp, 0, sizeof mp); 51 memset(vis, 0, sizeof vis); 52 ans = 0; 53 } 54 55 bool check(int x, int col) { 56 for (int i = 1; i <= n; ++i) { 57 if (mp[x][i]) { 58 if (vis[i] == col) return 0; 59 } 60 } 61 return 1; 62 } 63 64 void dfs(int x) { 65 if (x > n) { 66 cout << ++ans << " : "; 67 for (int i = 1; i <= n; ++i) { 68 cout << vis[i] << " "; 69 } 70 cout << endl; 71 return; 72 } 73 for (int i = 1; i <= m; ++i) { 74 vis[x] = i; 75 if (check(x, i)) dfs(x + 1); 76 vis[x] = 0; 77 } 78 } 79 80 int main() { 81 init();//初始化 82 cin >> n >> m >> cnt;//输入点数,颜色数,边数 83 while (cnt--) { 84 int u, v; 85 cin >> u >> v; 86 mp[u][v] = mp[v][u] = 1;//建立关系 87 } 88 dfs(1); 89 if (!ans) { 90 cout << "NO" << endl; 91 } 92 }