poj 1129 Channel Allocation(四色定理)

 1 #include<iostream>
 2 #include<cstdio>
 3 #include<cstdlib>
 4 #include<cstring>
 5 #include<string>
 6 #include<queue>
 7 #include<algorithm>
 8 #include<map>
 9 #include<iomanip>
10 #include<climits>
11 #include<string.h>
12 #include<numeric>
13 #include<cmath>
14 #include<stdlib.h>
15 #include<vector>
16 #include<stack>
17 #include<set>
18 #define FOR(x, b, e)  for(int x=b;x<=(e);x++)
19 #define REP(x, n)     for(int x=0;x<(n);x++)
20 #define INF 1e7
21 #define MAXN 100010
22 #define maxn 1000010
23 #define Mod 1000007
24 #define N 33
25 using namespace std;
26 typedef long long LL;
27 
28 
29 int G[N][N];
30 int col[N];
31 int n, cnt;
32 bool d[N];
33 
34 int main()
35 {
36     string tmp;
37     while (cin >> n, n) {
38         memset(G, 0, sizeof(G));
39         memset(col, 0, sizeof(col));
40         for (int k = 0; k < n; ++k) {
41             cin >> tmp;
42             for (int i = 0; tmp[i + 2]; ++i)
43                 G[tmp[0] - 'A' + 1][tmp[i + 2] - 'A' + 1] = 1;
44         }
45 
46         cnt = 0;
47         int i, j;
48         for (i = 1; i <= n; ++i) {
49             memset(d,0,sizeof(d));
50             for (j = 1; j <= i; ++j)        //寻找有冲突的频道编号 
51                 if (G[i][j]) d[col[j]] = 1;    //d[k]==1表示k频道有冲突 
52             for (j = 1;; j++)                //寻找可以使用的编号最小的频道 
53                 if (d[j] == 0) break;
54             col[i] = j;
55             cnt = max(cnt, j);
56         }
57         if (cnt == 1)
58             printf("%d channel needed.\n",cnt);
59         else 
60             printf("%d channels needed.\n", cnt);
61     }
62     return 0;
63 }
View Code
 1 < / pre><pre name = "code" class = "cpp">#include "stdio.h"
 2 #include "string.h"
 3 #include "algorithm"
 4 using namespace std;
 5 int map[26][26];
 6 int used[26];
 7 char ch[30];
 8 int n;
 9 /* 这个dfs是基于四色定理,所以dfs第一层循环i最大为4 
10    这种写法可以运作在四色定理的题目里,无向图任意的相邻两点颜色不同 
11 
12    */
13 void dfs(int node){
14     int flag, i, j;
15     if (node == n)
16         return;
17     for (i = 1; i <= 4; i++){
18         flag = 0;
19         //如果新结点与相邻结点颜色相同 则需要加颜色了,即i加1 
20         for (j = 0; j<n; j++){
21             if (map[node][j] && used[j] == i){
22                 flag = 1;
23                 break;
24             }
25         }
26         //这个if意思是如果新结点与相邻结点颜色都不相同,那么就染旧颜色,再搜索下一个结点 
27         if (!flag){
28             used[node] = i;
29             dfs(node + 1);
30             break;
31         }
32     }
33 }
34 
35 int main(){
36     int i, j;
37     while (scanf("%d", &n), n){
38         memset(map, 0, sizeof(map));
39         memset(used, 0, sizeof(used));
40         for (i = 0; i < n; i++){
41             scanf("%s", ch);
42             for (j = 2; j < strlen(ch); j++)
43             {
44                 map[i][ch[j] - 'A'] = 1;
45                 map[ch[j] - 'A'][i] = 1;
46             }
47         }
48         dfs(0);
49         sort(used, used + 26);
50         if (used[25] == 1)
51             printf("1 channel needed.\n");
52         else
53             printf("%d channels needed.\n", used[25]);
54     }
55 }
DFS

 

转载于:https://www.cnblogs.com/usedrosee/p/4375318.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值