csu1508 地图的四着色(剪枝+BFS DFS)

来源:互联网 发布:淘宝网的特点有哪些 编辑:程序博客网 时间:2024/06/10 01:18

题意:中文题

思路:首先男女各人用两种颜色,那么用A不用B和用B不用A时候的方案数是等价的,那么我们可以强行固定男先用A染色,女生先用C染色,最后方案数*4就是最后总的方案数。先用DFS/BFS把相同的城市标号,然后再次DFS/BFS把图的领接矩阵构造出来,然后再遍历一遍把邻接表构造出来。

           使用邻接表是因为可以快速地查找与它相邻的城市,而先构造邻接矩阵是因为要判重,然后直接固定一下他们染色的顺序就直接爆搜就可以了。实现起来还是有挺多细节的吧。

吐槽:用vector 19964MS卡过去了,自己实现的前向星10284MS。。


#include<iostream>#include<cstdio>#include<cstring>#include<queue>#include<vector>using namespace std;char mp[35][35];int vis[35][35],flag[35][35],mapp[35][35];//vector<int>e[35];struct Edge{int v,nxt;}edge[1005];int head[35],num;void add(int u,int v){edge[num].v=v;edge[num].nxt = head[u];head[u]=num++;}int color[35];int cnt=0;long long ans=0;int dir[4][2]={{1,0},{-1,0},{0,1},{0,-1}};int r,c;void bfs(int x,int y){++cnt;queue<pair<int,int> >q;q.push(make_pair(x,y));while(!q.empty()){pair<int,int> t = q.front();q.pop();vis[t.first][t.second]=cnt;        for(int i = 0;i<4;i++){int dx = t.first +dir[i][0];int dy = t.second+dir[i][1];if(dx<0 || dx>=r || dy<0||dy>=c)continue;if(vis[dx][dy] || mp[dx][dy]!=mp[t.first][t.second])continue;q.push(make_pair(dx,dy));}}}void bfs1(int x,int y){    queue<pair<int,int> >q;q.push(make_pair(x,y));while(!q.empty()){pair<int,int> t = q.front();q.pop();flag[t.first][t.second]=1;        for(int i = 0;i<4;i++){int dx = t.first +dir[i][0];int dy = t.second+dir[i][1];if(dx<0 || dx>=r || dy<0||dy>=c)continue;if(flag[dx][dy])continue;if(vis[t.first][t.second]!=vis[dx][dy]){mapp[vis[t.first][t.second]][vis[dx][dy]]=mapp[vis[dx][dy]][vis[t.first][t.second]]=1;continue;}q.push(make_pair(dx,dy));}}}bool check(int u,int co){for(int i = head[u];i!=-1;i=edge[i].nxt)if(color[edge[i].v]==co)return 0;return 1;//for(int i = 0;i<e[u].size();i++)//if(color[e[u][i]]==co)return 0;//return 1;}//当前第几个城市 A用了几个 B用了几个 C用了几个 D用了几个void dfs(int pos,int a,int b,int c,int d){     if(pos==cnt+1) { if(a&&b&&c&&d)ans++; return; }     color[pos]=0; if(check(pos,0))dfs(pos+1,a+1,b,c,d); color[pos]=1; if(check(pos,1) && a)dfs(pos+1,a,b+1,c,d); color[pos]=2; if(check(pos,2) && c+d<5)dfs(pos+1,a,b,c+1,d);     color[pos]=3; if(check(pos,3) && c+d<5 && c)dfs(pos+1,a,b,c,d+1);}void init(){     memset(vis,0,sizeof(vis)); memset(flag,0,sizeof(flag)); memset(color,0,sizeof(color));// for(int i = 0;i<35;i++)e[i].clear(); memset(mp,0,sizeof(mp)); memset(mapp,0,sizeof(mapp)); ans = 0; cnt = 0; memset(head,-1,sizeof(head)); num=0;}int cas = 1;int main(){ while(scanf("%d%d",&r,&c)!=EOF) { init();          for(int i = 0;i<r;i++)scanf("%s",mp[i]);  //get id  for(int i = 0;i<r;i++)  for(int j = 0;j<c;j++)  if(!vis[i][j])bfs(i,j);  for(int i = 0;i<r;i++)  for(int j = 0;j<c;j++)  if(!flag[i][j])bfs1(i,j);         for(int i = 1;i<=cnt;i++) for(int j = 1;j<i;j++) if(i!=j && mapp[i][j]) { add(i,j);// e[i].push_back(j); }         dfs(1,0,0,0,0); printf("Case %d: %lld\n",cas++,ans*4); }}


D - Four color map

 CSU - 1508 

0 0