HDU 4751 交叉染色判断二分图
2013-09-21 18:00
417 查看
九野的博客,转载请注明出处:http://blog.csdn.net/acmmmm/article/details/11877509
修改后的题意是:
n个点,下面n行
i行表示与i点相连的单向边,为0表示该行输入结束
问: 把点分到2个图中,每个图都要保证是完全图能否做到
问题等价于 保证不认识的不在同一个图里
显然这个图的补图就是一个二分图,BFS交叉染色判断图是否为二分图
代码1:
贴个学长的代码
修改后的题意是:
n个点,下面n行
i行表示与i点相连的单向边,为0表示该行输入结束
问: 把点分到2个图中,每个图都要保证是完全图能否做到
问题等价于 保证不认识的不在同一个图里
显然这个图的补图就是一个二分图,BFS交叉染色判断图是否为二分图
代码1:
#include <iostream> #include <string> #include <cstring> #include <algorithm> #include <cstdio> #include <cctype> #include <queue> #include <stdlib.h> #include <cstdlib> #include <math.h> #include <set> #include <vector> #define inf 107374182 #define N 200 #define M 20001 #define ll int using namespace std; inline ll Max(ll a,ll b){return a>b?a:b;} inline ll Min(ll a,ll b){return a<b?a:b;} struct Edge{ int f,t; }edge[M]; int edgenum; void addedge(int u,int v){ Edge E={u,v,}; edge[edgenum]=E; edgenum++; } //不认识的人一定在不同集合 int map ; int in ,n; bool BFS(int x){ queue<int>q; q.push(x); in[x]=0; while(!q.empty()){ x=q.front(); q.pop(); for(int i=1;i<=n;i++) { if(i==x || map[i][x]==1)continue;//x和i认识就不用考虑 if(in[i]==-1) { in[i]=in[x]^1; q.push(i); } else if(in[i]==in[x])return 1; } } return 0; } int main() { int i,j,m; while(~scanf("%d",&n)){ edgenum=0; memset(map,0,sizeof(map)); for(i=1;i<=n;i++){ scanf("%d",&m); while(m!=0){ map[i][m]=true; scanf("%d",&m); } } for(i=1;i<=n;i++) for(j=1;j<=n;j++) if(map[i][j]==0)map[j][i]=0; memset(in,-1,sizeof(in)); for(i=1;i<=n;i++) if(in[i]==-1) if(BFS(i))break; if(i>n)printf("YES\n"); else printf("NO\n"); } return 0; }
贴个学长的代码
#include<stdio.h> #include<iostream> #include<algorithm> #include<cstring> using namespace std; //const int inf = 1000000000; const int N = 500; const int M = N*N; struct E{ int v,next; }e[M]; int head ,k; int belong ,bcnt,dfn ,low ,ind; int stack ,top; bool vis ; int n; void add(int u,int v){ e[k].v = v; e[k].next = head[u]; head[u] = k++; } void tarjan(int u){ dfn[u] = low[u] = ++ind; vis[u] = true; stack[top++] = u; for(int i=head[u] ; i!=-1 ; i=e[i].next){ int v = e[i].v; if(!dfn[v]){ tarjan(v); if(low[u] > low[v]) low[u] = low[v]; }else if(vis[v] && dfn[v] < low[u]) low[u] = dfn[v]; } if(low[u] == dfn[u]){ bcnt++; int temp; do{ temp = stack[--top]; vis[temp] = false; belong[temp] = bcnt; }while(u != temp); } } void init(){ memset(head,-1,sizeof(head)); memset(dfn,0,sizeof(dfn)); memset(low,0,sizeof(low)); memset(vis,0,sizeof(vis)); k = top = ind = bcnt = 0; } int mp ; bool ok() { bool flag=1; int i; init(); for(int i=1;i<=n;i++) for(int j=i+1;j<=n;j++) if(mp[i][j]==0||mp[j][i]==0) { add(i,j+n); add(j,i+n); add(i+n,j); add(j+n,i); } for(i=1 ; i <= 2*n ; ++i) if(!dfn[i]) tarjan(i); for(i=1 ; i <=n ; ++i) if( belong[i] == belong[i+n] ) flag=0; return flag; } int main() { int x; while(scanf("%d",&n)!=EOF) { memset(mp,0,sizeof(mp)); for(int i=1;i<=n;i++) { while(1){ scanf("%d",&x); if(x==0) break; mp[i][x]=1; } } if(ok()) printf("YES\n"); else printf("NO\n"); } return 0; }
相关文章推荐
- HDU 4751 Divide Groups (判断二分图染色模板)
- HDU 4751 — Divide Groups 交叉染色判二分图
- 2013 ACM/ICPC Asia Regional Nanjing Online hdu 4751 补图+二分图染色判定
- hdu 2444(染色法判断二分图+匈牙利算法)
- HDU 5285 wyh2000 and pupil(染色法判断二分图)
- HDU 4751 Divide Groups (2013南京网络赛1004题,判断二分图)
- hdu 2444(染色法判断二分图+匈牙利算法)
- HDU 4751 Divide Groups 二分图判断
- HDU 4751 Divide Groups(判断是否为二分图)
- HDU 4751 (判断二分图)
- HDU 4751 Divide Groups(二分图判断)
- hdu 2444 交叉染色判断二分图+二分最大匹配
- HDU 4751 Divide Groups(判断二分图)
- hdu 2444 交叉染色判断二分图+二分最大匹配
- hdu 4751 Divide Groups (二分图判断)
- hdu 5285(染色法判断二分图)
- HDU 4751 Divide Groups【二分图染色】
- HDU 4751 Divide Groups(二分图的判断)
- hdu 2444(染色法判断二分图+最大匹配)
- hdu 2444 The Accomodation of Students 染色判断是否为二分图