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
- csu1508 地图的四着色(剪枝+BFS DFS)
- CSU-1508 地图的四着色【Bfs+Dfs+思维剪枝】
- csu 1508 地图的四着色(BFS,DFS,巧妙剪枝)
- 每日三题-Day6-C(CSU 1508 地图的四着色 巧妙剪枝搜索dfs)
- hdu Nightmare(BFS||DFS)(不标记的剪枝)
- CSU_1508_地图的四着色
- csu_1508_地图的四着色
- CSU 1508 地图的四着色
- 地图的四着色 中南1508
- 地图四着色问题
- UVA-11882 bfs + dfs + 剪枝
- UVA 11882 Biggest Number (搜索+剪枝(dfs+bfs))
- HDU 1728 逃离迷宫(dfs或bfs+剪枝)
- HDU 1072 Nightmare(DFS或BFS+剪枝)
- 搜索专题(DFS&&BFS&&剪枝)HDU 1728-逃离迷宫
- UVA 11882 Biggest Number (dfs搜索+bfs 剪枝)
- uscoj:1346 & csuoj:1508 地图的四着色
- poj1184 聪明的打字员(BFS剪枝)
- ListView中TextView的适配
- jquery 点击旋转效果,点击图片旋转360度
- 【Usaco 2007 Dec gold】队列变换
- 替换空格
- poj2996
- csu1508 地图的四着色(剪枝+BFS DFS)
- 浅谈构造函数与析构函数的调用顺序
- Linux的五个查找命令:find,locate,whereis,which,type
- itextpdf的使用之中文字体
- C#程序中判断DEBUG和RELEASE状态
- 1.1 理解网络编程和套接字
- gcc4.1.2通过rpm包升级gcc4.4.7
- TSP_旅行商问题 - 遗传算法(四)
- 公司ubuntu服务器登录与操作记录