【DFS】CODE[VS] 1535 封锁阳光大学(二分图DFS染色)
2016-10-30 11:09
477 查看
点击进入异世界
这个题,题意是给图染色判断是否为二分图
什么事二分图呢
顾名思义是可以将一个图中的点分为两个集合的图
这道题既可以用DFS也可以用BFS,先写下DFS的做法(比我写的BFS快一些)
二分图满足一个性质:不存在拥有奇数条边的环。如果存在则不是二分图因为,在二分图定义中,同属一个集合的点互相之间是没有连边的,若存在奇数环,则说明同集合点一定有连边。
如下图所示:
当有环且环上边数为偶数时
同集合点是没有连边的,也就是说一条边的两端点一定所属集合不同
当有环且环上边数为奇数时
左边点集中有两点连边,该边的两端点所属集合相同
二分图染色,就是将一个图按照二分图的规则对图中的点进行划分,若可以完成染色则说明该图是二分图
回到题目,题目实际上就是让我们进行二分图染色看是不是二分图
定义sum[1]是“黑色”,sum[2]是“白色”,在搜索每个连通子图(数据可能有的子图互相之间不连通)的时候,初始化搜索的第一个点为sum[1];
开始枚举,如果这个点没有遍历到则取与他父节点相反的颜色
若这个图遍历过,则判断其与其父节点的颜色是否相同,若相同则输出“Impossible”
这个题打了好几份代码,只有一份能AC,其余的都50分,这里附上两份
第一个打傻了的DFS+Trajan(50分)
当时混淆了双连通和连通,然后就没有与然后了….居然还能过5个点orz(垃圾代码,注释懒得删了)
第二份是”极为正常”的DFS,要从1for到n,如果这个点没到过,就DFS递归调用
THE END
By Peacefuldoge
http://blog.csdn.net/loi_peacefuldog
这个题,题意是给图染色判断是否为二分图
什么事二分图呢
顾名思义是可以将一个图中的点分为两个集合的图
这道题既可以用DFS也可以用BFS,先写下DFS的做法(比我写的BFS快一些)
二分图满足一个性质:不存在拥有奇数条边的环。如果存在则不是二分图因为,在二分图定义中,同属一个集合的点互相之间是没有连边的,若存在奇数环,则说明同集合点一定有连边。
如下图所示:
当有环且环上边数为偶数时
同集合点是没有连边的,也就是说一条边的两端点一定所属集合不同
当有环且环上边数为奇数时
左边点集中有两点连边,该边的两端点所属集合相同
二分图染色,就是将一个图按照二分图的规则对图中的点进行划分,若可以完成染色则说明该图是二分图
回到题目,题目实际上就是让我们进行二分图染色看是不是二分图
定义sum[1]是“黑色”,sum[2]是“白色”,在搜索每个连通子图(数据可能有的子图互相之间不连通)的时候,初始化搜索的第一个点为sum[1];
开始枚举,如果这个点没有遍历到则取与他父节点相反的颜色
若这个图遍历过,则判断其与其父节点的颜色是否相同,若相同则输出“Impossible”
这个题打了好几份代码,只有一份能AC,其余的都50分,这里附上两份
第一个打傻了的DFS+Trajan(50分)
当时混淆了双连通和连通,然后就没有与然后了….居然还能过5个点orz(垃圾代码,注释懒得删了)
#include <cstdio> #include <cstring> #include <iostream> #include <algorithm> #include <stack> const int maxn = 120100; using namespace std; int tot; int n,m; int ans; int qlt[maxn]; int head[maxn]; int color[maxn]; bool motherfucker; bool vis[maxn]; struct node{ int f,t,next; }e[maxn << 1]; inline void build(int x,int y) { //cout<<"------------------------------------"<<endl; tot++; //cout<<"head_after of "<<x<<" : "<<head[x]<<endl; e[tot].f = x; e[tot].t = y; //cout<<tot<<" to : "<<e[tot].t<<endl; e[tot].next = head[x]; //cout<<tot<<" next : "<<e[tot].next<<endl; head[x] = tot; //cout<<"head_fin of "<<x<<" : "<<head[x]<<endl; //cout<<"------------------------------------"<<endl; } inline void dfs(int w,int muy1) { //cout<<"当前的w为"<<w<<"muy1为"<<muy1<<endl; //cout<<"ans_after: "<<ans<<endl; //cout<<"color of "<<w<<" is "<<color[w]<<endl; //cout<<"motherfucker: "<<motherfucker<<endl; ans = max(ans , muy1); //cout<<"ans_fin: "<<ans<<endl; //cout<<"head of "<<w<<" is "<<head[w]<<endl; for(int i = head[w];i;i = e[i].next) { //cout<<"i----> "<<i<<endl; //cout<<"colorw of "<<w<<" : "<<color[w]<<endl; //cout<<"color of "<<e[i].t<<" : "<<color[e[i].t]<<endl; int cmuy = muy1; if(color[e[i].t] == 0) { if(color[w] == 1&&vis[e[i].t] != 1) color[e[i].t] = 2; if(color[w] == 2&&vis[e[i].t] != 1) { muy1++; color[e[i].t] = 1; } dfs(e[i].t,muy1); muy1 = cmuy; } else if(color[w] == color[e[i].t]) { //cout<<color[w]<<" "<<color[e[i].t]<<endl; motherfucker = 1; //cout<<"now of motherfucker : "<<motherfucker<<endl; } } } int lowlink[maxn],sccno[maxn],clockw,cnt; stack<int >s; void tj(int u) { cout<<u<<endl; qlt[u] = lowlink[u] = ++clockw; cout<<"lowlink of "<<u<<" "<<lowlink[u]<<endl; s.push(u); cout<<"stack : "<<s.top()<<endl; for(int i = head[u];i;i = e[i].next) { int v = e[i].t; if(!qlt[v]) { tj(v); lowlink[u] = min(lowlink[u],lowlink[v]); } else if(!sccno[v]) { lowlink[u] = min(lowlink[u],qlt[v]); } } if(lowlink[u] == qlt[u]) { cnt++; for(;;) { int x = s.top(); s.pop(); sccno[x] = cnt; if(x == u||s.empty()) break; } } } void find_scc(int xx) { clockw = cnt = 0; memset(sccno,0,sizeof(sccno)); memset(qlt,0,sizeof(qlt)); for(int i = 1;i <= xx;i++) { if(!qlt[i]) tj(i); } } bool cntused[maxn]; int main() { memset(color,0,sizeof(color)); scanf("%d%d",&n,&m); for(int i = 1;i <= m;i++) { int aa,bb; scanf("%d%d",&aa,&bb); build(aa,bb); build(bb,aa); } vis[1] = 1; color[1] = 1; find_scc(n); for(int i = 1;i <= n;i++) { if(cntused[sccno[i]] == 0) { cntused[sccno[i]] = 1; dfs(i,1); } if(cntused[sccno[i]] == 1) continue; } if(motherfucker == 1) printf("Impossible\n"); //cout<<"fuckyou"<<endl; if(motherfucker == 0) { int dc = n-ans; if(ans > dc) { for(int i = 1;i <= n;i++) { if(head[i] == 0) dc++; } printf("%d\n",dc); } else { for(int i = 1;i <= n;i++) { if(head[i] == 0) ans++; } printf("%d\n",ans); } } return 0; }
第二份是”极为正常”的DFS,要从1for到n,如果这个点没到过,就DFS递归调用
#include <cstdio> #include <cstring> #include <iostream> #include <algorithm> const int maxn = 10010; using namespace std; int tot; int ans; int n,m; int color[maxn]; int head[maxn]; int sum[3]; bool vis[maxn]; struct node{ int f; int t; int next; }e[maxn << 1]; inline void build(int ff,int tt) { tot++; e[tot].f = ff; e[tot].t = tt; e[tot].next = head[ff]; head[ff] = tot; } inline bool dfs(int x,int cnt) { vis[x] = 1; color[x] = cnt; sum[cnt]++; for(int i = head[x];i;i = e[i].next) { int u = e[i].t; if(vis[u] == 1) { if(color[x] == color[u]) return false; } else { if(color[x] == 1) dfs(u,2); if(color[x] == 2) dfs(u,1); } } return true; } int main() { scanf("%d%d",&n,&m); for(int i = 1;i <= m;i++) { int a,b; scanf("%d%d",&a,&b); build(a,b); build(b,a); } for(int i = 1;i <=n;i++) { sum[1] = sum[2] = 0; if(vis[i] == 0) { if(dfs(i,1) == false) { printf("Impossible\n"); return 0; } ans += min(sum[1],sum[2]); } } printf("%d\n",ans); return 0; }
THE END
By Peacefuldoge
http://blog.csdn.net/loi_peacefuldog
相关文章推荐
- 【BFS】CODE[VS] 1535 封锁阳光大学(二分图BFS染色)
- <二分图染色>codevs 1535 封锁阳光大学
- Codevs 1535 封锁阳光大学
- codevs 1535 封锁阳光大学
- 洛谷 1330 封锁阳光大学 图论 二分图染色
- atcoder/CODE FESTIVAL 2017 qual B/B(dfs染色判断是否为二分图)
- 洛谷 1330 封锁阳光大学 图论 二分图染色
- [codevs1022]覆盖(染色+二分图最大匹配)
- dfs染色——洛谷 P1330 封锁阳光大学
- 洛谷 1330 封锁阳光大学 图论 二分图染色
- 洛谷 1330 封锁阳光大学 图论 二分图染色
- CODEVS1022 覆盖 (二分图染色+匈牙利算法)
- 洛谷 1330 封锁阳光大学 图论 二分图染色
- 洛谷 P1330 封锁阳光大学 二分图染色模板
- 洛谷 1330 封锁阳光大学 图论 二分图染色
- 洛谷 1330 封锁阳光大学 图论 二分图染色
- 洛谷 1330 封锁阳光大学 图论 二分图染色
- 洛谷 1330 封锁阳光大学 图论 二分图染色
- 洛谷P1330封锁阳光大学[二分图染色]
- codeforce 742 E. Arpa’s overnight party and Mehrdad’s silent entering (分食物||二分图染色+dfs)