您的位置:首页 > 其它

POJ 1129 Channel Allocation DFS+四色问题优化

2016-08-15 09:53 429 查看
一道DFS题,能过采用四色问题的结论进行优化。

题目链接:http://poj.org/problem?id=1129

问题是说有n个广播站,相邻的广播站为了避免干扰,需要用不同的频道,最少需要有多少个频道。

这个问题由于广播站直接的相邻关系和平面图像的相邻关系相似,于是可以抽象为一个平面图涂色,相邻区块不能涂相同的颜色。结论是最多需要4种颜色,于是在DFS的时候3种颜色不行就能够直接输出答案4。

Ans表示需要多少种颜色。可以先假定只需要一种颜色,即ans = 1。具体的实现是对每一个节点,枚举它还能过被涂的颜色。如果发现没有找到结果,那么只需要ans++,再次进行DFS过程,直到找到一个合法的解或者ans
= 4。这种做法的正确性是显然的。

PS:还有一个坑就是答案为1的时候,输出的是channel,其余的是channels!被坑了好久

 

AC代码:

 

#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <vector>
#include <string.h>
using namespace std;

int next[26][26];
int ln[26];
int flag[26];
int n,ans;
string s;

bool dfs(int x)	//深搜到第x个节点
{
int i,j,a,b,k;
if(x==n)//边界判定
{
return true;
}
int mark[4];//记录颜色是否能选(四色问题结论优化
memset(mark,0,sizeof(mark));
for(i=0;i<ln[x];i++)//枚举相邻节点,记录已有颜色
{
a=x;b=next[x][i];
mark[flag[b]]=1;//flag[x]表示第x个节点的颜色
}
for(i=1;i<=ans;i++)	//枚举可填的颜色
{
if(mark[i]==0)
{
flag[x]=i;
if(dfs(x+1))//深搜x+1
{
flag[x]=0;
return true;
}
}
}
flag[x]=0;
if(x!=0) return false;//回溯,若不是初始节点,返回false,否则ans++继续搜
ans++;
if(ans==4) return true;
return dfs(0);

}

int main()
{
int i,j,a,b;
while(cin>>n)
{
if(n==0) return 0;
memset(ln,0,sizeof(ln));
memset(next,0,sizeof(next));
memset(flag,0,sizeof(flag));
for(i=0;i<n;i++)//读入数据
{
cin>>s;
a=s[0]-'A';
for(j=2;j<s.size();j++)
{
b=s[j]-'A';
next[a][j-2]=b;//记录后继
ln[a]++;//记录后继长度,ln++
}
}
ans=1;
dfs(0);	//dfs
if(ans==1)
cout<<"1 channel needed."<<endl;
//注意答案为1时输出单数形式
else
cout<<ans<<" channels needed."<<endl;
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: