【tarjan求双连通分量+染色判二分图】POJ 2942
2012-03-15 02:08
351 查看
这题debug的好郁闷啊!!!先是染色有问题,然后就是各种小错误....
判奇圈可以用二分图标准,因为奇圈肯定不是二分图,之前还要分离各双连通分量.......染色法判二分图一定要先对分量里每一个点都染一次色再枚举任意两个相邻的点看是否有同色,就是因为这里wa了n次!!!
判奇圈可以用二分图标准,因为奇圈肯定不是二分图,之前还要分离各双连通分量.......染色法判二分图一定要先对分量里每一个点都染一次色再枚举任意两个相邻的点看是否有同色,就是因为这里wa了n次!!!
#define N 1005 vector<int> v ; vector<int> lin ; int dfn ,low ; bool instack ,iscut ; int num_rt; int cnt; int step; stack<int> sta; bool g ; void init(int n){ for(int i=0;i<=n;i++){ instack[i] = 0; iscut[i] = 0; dfn[i] = 0; low[i] = 0; } step = 0; cnt = 0; while(!sta.empty())sta.pop(); } void tarjan(int u,int fa){ low[u] = dfn[u] = ++step; sta.push(u); instack[u] = 1; int i; for(i=0;i<v[u].size();i++){ int to = v[u][i]; if(to==fa)continue; if(!dfn[to]){ tarjan(to,u); low[u] = min(low[u],low[to]); if(low[to]>=dfn[u]){ if(fa==-1)num_rt++; else iscut[u] = 1; while(1){ int tmp = sta.top(); sta.pop(); iscut[tmp] = 0; instack[tmp] = 0; lin[cnt].push_back(tmp); if(tmp==to)break; } lin[cnt].push_back(u); cnt++; } } else if(instack[to]) low[u] = min(low[u],dfn[to]); } } int col ; bool dfs(int id,int u,int c){ int i; col[u] = c; for(i=0;i<lin[id].size();i++){ int to = lin[id][i]; if(u==to || col[to]!=-1)continue; if(g[u][to]){ dfs(id,to,c^1); } } return true; } bool ok ; int solve(int n){ int i,j; for(i=1;i<=n;i++){ if(!dfn[i]){ num_rt = 0; tarjan(i,-1); if(num_rt>=2){ iscut[i] = 1; } } } int ans = 0; memset(ok,false,sizeof(ok)); bool tag = 0; for(i=0;i<cnt;i++){ for(j=0;j<=n;j++)col[j]=-1; int sz = lin[i].size(); dfs(i,lin[i][0],1); bool tag = 0; for(j=0;j<sz;j++){ for(int k=0;k<sz;k++){ int a = lin[i][j],b = lin[i][k]; if(a!=b && g[a][b] && col[a]==col[b]){ tag = 1; break; } } if(tag)break; } if(tag){ for(j=0;j<sz;j++){ ok[lin[i][j]] = 1; } } } for(i=1;i<=n;i++){ if(!ok[i])ans++; } return ans; } int main(){ int n,m; while(scanf("%d%d",&n,&m) &&(n+m)){ int i,j; memset(g,true,sizeof(g)); init(n); while(m--){ int x,y; scanf("%d%d",&x,&y); g[x][y] = g[y][x] = false; } for(i=0;i<=n;i++){ v[i].clear(); lin[i].clear(); } for(i=1;i<=n;i++){ for(j=1;j<=n;j++){ if(g[i][j] && i!=j){ v[i].push_back(j); } } } printf("%d\n",solve(n)); } return 0; }
相关文章推荐
- POJ2942 Knights of the Round Table(点双连通分量 + 二分图染色)
- POJ2942 Knights of the Round Table[点双连通分量|二分图染色|补图]
- POJ 2942 Knights of the Round Table [二分图染色][点双连通分量]
- 【poj 2942 】 Knights of the Round Table 【tarjan求bcc+黑白染色判二分图】
- 【POJ 2942】Knights of the Round Table(点双连通分量,二分图染色)
- POJ 2942:Knights of the Round Table tarjan点双联通分量 二分图染色找奇环
- [POJ]2942 圆桌骑士 点双连通分量 + 二分图染色
- poj 2942 Knights of the Round Table Tarjan求点双联通分量+黑白染色二分图判断
- POJ 2942 Knights of the Round Table(点双联通+二分图+染色)
- 图论总结 Dijkstra Tarjan 最小生成树 二分图 最短路 强连通分量 双连通分量 Bellman-Ford SPFA 二分图染色 Kruskal Prim 网络流 二分图匹配 Dinic
- poj 2942 Knights of the Round Table 补图+点双连通分量+判定二分图
- poj 2942 点双连通分量+二分图染色
- poj 2942 双连通分量+染色判二部图(驱除骑士)
- poj 2942 双连通分量+二分图的染色判断
- POJ 2942 Tarjan双联通分量+二分图 解题报告
- poj 2942 双连通+tarjan+割点+奇环判断+二分图染色
- POJ 2942 点双联通+二分图染色
- poj2942(双联通分量,交叉染色判二分图)
- poj2942(双联通分量,交叉染色判二分图)
- Knights of the Round Table 补图, 双连通分量,奇圈,二分图,染色(交叉染色),(tarjan)