poj 2942 (点双联通+判断二分图)
来源:互联网 发布:铝塑板折边工具淘宝 编辑:程序博客网 时间:2024/06/02 23:13
poj 2942 (点双联通+判断二分图)
分类: 强连通—双连通—LCA—2-SAT2013-09-23 17:58 80人阅读 评论(0) 收藏 举报
ACM编程算法百度Tarjan
如何判断一个图中是否存在回路
2011-12-30 20:22:50| 分类: 算法 | 标签:图中回路问题 bfs dfs 圈的个数 拓扑排序 |字号 订阅
如何判断一个图是否是二分的?
2011-12-30 17:40:46| 分类: 算法 | 标签:二分图判定 bfs |字号 订阅
题意:亚瑟王要在圆桌上召开骑士会议,为了不引发骑士之间的冲突,并且能够让会议的议题有令人满意的结果,每次开会前都必须对出席会议的骑士有 如下要求:1:相互憎恨的两个骑士不能坐在直接相邻的2个位置;2:出席会议的骑士数必须是奇数,这是为了让投票表决议题时都能有结果。
现在给定准备去开会的骑士数n,再给出m对憎恨关系(表示某2个骑士之间是互相憎恨的),问有多少骑士不管跟哪些骑士都无法组成圆桌会议?
思路:没有矛盾的骑士之间建边,能组成圆桌会议的肯定形成一个环,并且环的点数为奇数。可以用Tarjan求出点双联通分量,判断每个联通分量是否存在 奇环,如果存在奇环的话,该联通分量的所有节点都可以参加会议。一个图是二分图是不存在奇环的充要条件,所以只需要判断该联通分量是否是二分图 即可。
- #include<stdio.h>
- #include<stack>
- #include<math.h>
- #include<string.h>
- const int N=1010;
- using namespace std;
- int cnt[N],low[N],dfs[N],head[N],num,ans,idx,first[N],color[N],flag,n,eenum;
- bool map[N][N],vis[N];
- struct edge
- {
- int st,ed,next;
- }e[N*N],ee[N*N];
- void addedge(int x,int y)
- {
- e[num].st=x;e[num].ed=y;e[num].next=head[x];head[x]=num++;
- e[num].st=y;e[num].ed=x;e[num].next=head[y];head[y]=num++;
- }
- void Addedge(int x,int y)
- {
- ee[eenum].st=x;ee[eenum].ed=y;ee[eenum].next=first[x];first[x]=eenum++;
- ee[eenum].st=y;ee[eenum].ed=x;ee[eenum].next=first[y];first[y]=eenum++;
- }
- bool Judge(int u,int cor)//判断二分图
- {
- color[u]=cor;
- int i,v;
- for(i=first[u];i!=-1;i=ee[i].next)
- {
- v=ee[i].ed;
- if(color[v]==-1)
- {
- return Judge(v,cor^1);
- }
- else if(color[v]==color[u])return true;//不是二分图
- }
- return false;
- }
- stack<int>Q;
- void Tarjan(int u,int id)
- {
- int v,i,temp,j;
- dfs[u]=low[u]=idx++;
- for(i=head[u];i!=-1;i=e[i].next)
- {
- v=e[i].ed;
- if(i==(id^1))continue;
- if(dfs[v]==-1)
- {
- Q.push(i);
- Tarjan(v,i);
- low[u]=low[u]>low[v]?low[v]:low[u];
- if(dfs[u]<=low[v])//u为割点
- {
- memset(first,-1,sizeof(first));
- memset(color,-1,sizeof(color));
- eenum=0;
- do
- {
- temp=Q.top();
- Q.pop();
- Addedge(e[temp].st,e[temp].ed);
- }while(temp!=i);//一个双联通分量的所有边
- if(Judge(u,0))//如果不是二分图该联通分量里所有点都可以参加会议
- {
- for(j=0;j<eenum;j+=2)
- vis[ee[j].st]=vis[ee[j].ed]=true;
- }
- }
- }
- else if(low[u]>dfs[v])
- {
- Q.push(i);
- low[u]=dfs[v];
- }
- }
- }
- int main()
- {
- int m,x,y,i,j,sum,Case=0;
- while(scanf("%d%d",&n,&m)!=-1&&n+m)
- {
- memset(head,-1,sizeof(head));
- memset(map,false,sizeof(map));
- num=0;
- for(i=0;i<m;i++)
- {
- scanf("%d%d",&x,&y);
- map[x][y]=map[y][x]=true;
- }
- for(i=1;i<=n;i++)
- {
- for(j=i+1;j<=n;j++)
- if(map[i][j]==false)
- addedge(i,j);
- }
- memset(dfs,-1,sizeof(dfs));
- memset(vis,false,sizeof(vis));
- ans=idx=0;sum=0;
- for(i=1;i<=n;i++)//图可能不连通
- {
- if(dfs[i]==-1)
- Tarjan(i,-1);
- }
- for(i=1;i<=n;i++)
- if(!vis[i])
- sum++;
- printf("%d\n",sum);
- }
- return 0;
- }
- poj 2942 (点双联通+判断二分图)
- poj 2942 (点双联通+判断二分图)
- POJ 2942 点双联通+二分图染色
- POJ 2942 - Knights of the Round Table(点双联通+二分图)
- POJ 2942 Knights of the Round Table(点双联通+二分图+染色)
- POJ 2942:Knights of the Round Table tarjan点双联通分量 二分图染色找奇环
- poj 2942 求点双联通+二分图判断奇偶环+交叉染色法判断二分图
- poj-2942-点双联通
- POJ 2942 Tarjan双联通分量+二分图 解题报告
- POJ 2375 强联通缩点+判断
- hdu3478(图的联通+二分图判断)
- poj 2942 奇圈+点双联通分量
- 点双联通和二分图着色(二分图判定)模板
- poj 3694双联通缩点+LCA
- poj 3352 (双联通缩点)
- poj 3177 双联通缩点
- poj 2942 双连通+tarjan+割点+奇环判断+二分图染色
- POJ 2186 强联通缩点+判断+找出度为0的点
- nyoj-660-逃离地球
- js跨浏览器将字符串转化为xml对象
- 测试流程规范
- Amazon Campus(2013-Sep-24)Question 2 / 2 (Amazon Campus(17):Find the differences of items in amazon)
- 用递归求最大公约数
- poj 2942 (点双联通+判断二分图)
- scanf()函数的用法和实践
- PHP验证码图片在各类平台中的应用
- VMware’s Strategy for Software-Defined Storage
- json 简介
- 99乘法表打印
- Oracle索引分类
- table标题栏悬浮一直显示
- Web前端优化最佳实践及工具集锦