题意:在广播时,相邻的中继器会互相干扰,为了避免干扰,可以让中继器使用不同的通道。现在给出n个中继器,以及分别与它们相邻的中继器。求最少需要的通道数。
题解:给出两组代码,第二组用到了四色定理。
四色定理(Four color theorem)最先是由一位叫古德里(Francis Guthrie)的英国大学生提出来的。四色问题的内容是:“任何一张地图只用四种颜色就能使具有共
边界的国家着上不同的颜色。”用数学语言表示,即“将平面任意地细分为不相重叠的区域,每一个区域总可以用1,2,3,4这四个数字之一来标记,而不会使相邻的两个区域得到相同的数字。”这里所指的相邻区域,是指有一整段边界是公共的。如果两个区域只相遇于一点或有限多点,就不叫相邻的。因为用相同的颜色给它们着色不会引起混淆。
#include <iostream> using namespace std; char str[30]; bool map[30][30]; int chan[30]; int n,res; bool isLeagal( int nth, int id ) { for ( int i = 1; i < nth; i++ ) //若中继器 i 与中继器 nth 有关联且通道id已经被使用,则不可行。 if ( map[i][nth] && chan[i] == id ) return false; return true; } void dfs( int nth, int mini ) // mini带代表了通道的个数,编号1,2,3,4... 若通道N被使用,则说明至少需要N个通道。 { if ( nth > n ) { if ( mini < res ) res = mini; return; } for ( int i = 1; i <= mini; i++ ) { if ( isLeagal(nth,i) ) // 不增加通道个数,即在编号1...mini的通道中为第nth个中继器选择通道 { chan[nth] = i; dfs(nth+1,mini); } } chan[nth] = mini+1; // 选择第nth个中继器的通道为编号mini+1的通道 dfs(nth+1,mini+1); } int main() { while ( cin >> n && n ) { memset(map,0,sizeof(map)); memset(chan,0,sizeof(chan)); for ( int i = 1; i <= n; i++ ) { cin >> str; for ( int j = 2; str[j]; j++ ) map[str[0]-'A'+1][str[j]-'A'+1] = map[str[j]-'A'+1][str[0]-'A'+1] = true; } res = 30; dfs(1,0); if ( res == 1 ) cout << res << " channel needed." << endl; else cout << res << " channels needed." << endl; } return 0; }
#include <iostream> using namespace std; char str[30]; int map[30][30]; int color[30]; int n; bool isLegal ( int x, int temp ) { for ( int i = 1; i < x; i++ ) if ( map[i][x] && color[i] == temp ) return false; return true; } bool dfs ( int x, int c ) { if ( x > n ) return true; for ( int i = 1; i <= c; i++ ) { if ( isLegal(x,i) ) { color[x] = i; if ( dfs(x+1,c) ) return true; } } return false; } int main() { while ( cin >> n && n ) { int i,j; memset(map,0,sizeof(map)); for ( i = 1; i <= n; i++ ) { cin >> str; for ( j = 2; str[j]; j++ ) map[str[0]-'A'+1][str[j]-'A'+1] = map[str[j]-'A'+1][str[0]-'A'+1] = true; } for ( i = 1; i <= 4; i++ ) /* 分别判断用 1个, 2个, 3个, 4个通道能否实现要求 */ { if ( dfs(1,i) ) break; } if ( i == 1 ) cout << i << " channel needed." << endl; else cout << i << " channels needed." << endl; } return 0; }