分析:我们对于那些相互不憎恨的人连边,将每次参加会议的所有人(不一定是全部人,只需人数>=3且为奇数)看做一个点双联通分量,那么每个点都至少有两个点与他相邻。即需要保证双联通分量中存在奇圈。至于如何判奇圈,这里有一个性质:一个图是二分图当且仅当图中不存在奇圈。至于如何判断一个图是否是二分图,可以采用交替染色的方式判断。

传送门:FZU 2181 快来买肉松饼

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<stack>
using namespace std;
#define MAXN 1005 struct Edge{
int v,next;
}edge[MAXN*MAXN*]; int n,m,NE,ans;
int head[MAXN];
bool hate[MAXN][MAXN];
void Insert(int u,int v)
{
NE++;
edge[NE].v=v;
edge[NE].next=head[u];
head[u]=NE;
} void Build()
{
int a,b;
memset(hate,false,sizeof(hate));
while(m--){
scanf("%d%d",&a,&b);
hate[a][b]=hate[b][a]=true;
}
for(int i=;i<=n;i++){
for(int j=i+;j<=n;j++){
if(!hate[i][j]){
Insert(i,j);
Insert(j,i);
}
}
}
} int cnt,_count;
int low[MAXN],dfn[MAXN];
int block[MAXN];
int color[MAXN];
bool mark[MAXN];
int num[MAXN];
bool is_expelled[MAXN];
stack<int>S;
bool Judge(int u,int state)
{
color[u]=state;
for(int i=head[u];i;i=edge[i].next){
int v=edge[i].v;
if(block[v]==_count){
if(color[v]&&color[u]==color[v])
return true;
if(!color[v]&&Judge(v,-state))
return true;
}
}
return false;
}
void Tarjan(int u,int father)
{
int flag=;
low[u]=dfn[u]=++cnt;
mark[u]=true;
S.push(u);
for(int i=head[u];i;i=edge[i].next){
int v=edge[i].v;
if(v==father&&!flag){ flag=;continue; }
if(dfn[v]==){
Tarjan(v,u);
low[u]=min(low[u],low[v]);
if(low[v]>=dfn[u]){
int x,tmp=;
_count++;
do{
x=S.top();
S.pop();
mark[x]=false;
block[x]=_count;
num[tmp++]=x;
}while(x!=v);//割点u可能属于多个连通块,因此不能出栈
num[tmp++]=u;
memset(color,,sizeof(color));
if(tmp>=&&Judge(u,)){
while(tmp>){
is_expelled[num[--tmp]]=false;
}
}
}
}else if(mark[v]){
low[u]=min(low[u],dfn[v]);
}
}
}
void init()
{
cnt=_count=;NE=;
memset(head,,sizeof(head));
memset(dfn,,sizeof(dfn));
memset(low,,sizeof(low));
memset(block,,sizeof(block));
memset(is_expelled,true,sizeof(is_expelled));
memset(mark,false,sizeof(mark));
}
int main()
{
int T,k;
scanf("%d",&T);
while(T--){
// if(n==0&&m==0)break;
scanf("%d%d%d",&n,&m,&k);
init();
Build();
for(int i=;i<=n;i++)if(dfn[i]==)Tarjan(i,-);
ans=;
for(int i=;i<=n;i++)if(!is_expelled[i])ans++;
if(ans>=k)puts("Let's Fire!");
else puts("What a Pity.");
//printf("%d\n",ans);
}
return ;
}

传送门:poj 2942 Knights of the Round Table

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<stack>
using namespace std;
#define MAXN 1005 struct Edge{
int v,next;
}edge[MAXN*MAXN*]; int n,m,NE,ans;
int head[MAXN];
bool hate[MAXN][MAXN];
void Insert(int u,int v)
{
NE++;
edge[NE].v=v;
edge[NE].next=head[u];
head[u]=NE;
} void Build()
{
int a,b;
memset(hate,false,sizeof(hate));
while(m--){
scanf("%d%d",&a,&b);
hate[a][b]=hate[b][a]=true;
}
for(int i=;i<=n;i++){
for(int j=i+;j<=n;j++){
if(!hate[i][j]){
Insert(i,j);
Insert(j,i);
}
}
}
} int cnt,_count;
int low[MAXN],dfn[MAXN];
int block[MAXN];
int color[MAXN];
bool mark[MAXN];
int num[MAXN];
bool is_expelled[MAXN];
stack<int>S;
bool Judge(int u,int state)
{
color[u]=state;
for(int i=head[u];i;i=edge[i].next){
int v=edge[i].v;
if(block[v]==_count){
if(color[v]&&color[u]==color[v])
return true;
if(!color[v]&&Judge(v,-state))
return true;
}
}
return false;
}
void Tarjan(int u,int father)
{
int flag=;
low[u]=dfn[u]=++cnt;
mark[u]=true;
S.push(u);
for(int i=head[u];i;i=edge[i].next){
int v=edge[i].v;
if(v==father&&!flag){ flag=;continue; }
if(dfn[v]==){
Tarjan(v,u);
low[u]=min(low[u],low[v]);
if(low[v]>=dfn[u]){
int x,tmp=;
_count++;
do{
x=S.top();
S.pop();
mark[x]=false;
block[x]=_count;
num[tmp++]=x;
}while(x!=v);//割点u可能属于多个连通块,因此不能出栈
num[tmp++]=u;
memset(color,,sizeof(color));
if(tmp>=&&Judge(u,)){
while(tmp>){
is_expelled[num[--tmp]]=false;
}
}
}
}else if(mark[v]){
low[u]=min(low[u],dfn[v]);
}
}
}
void init()
{
cnt=_count=;NE=;
memset(head,,sizeof(head));
memset(dfn,,sizeof(dfn));
memset(low,,sizeof(low));
memset(block,,sizeof(block));
memset(is_expelled,true,sizeof(is_expelled));
memset(mark,false,sizeof(mark));
}
int main()
{
while(scanf("%d%d",&n,&m)>){
if(n==&&m==)break;
init();
Build();
for(int i=;i<=n;i++)if(dfn[i]==)Tarjan(i,-);
ans=;
for(int i=;i<=n;i++)if(is_expelled[i])ans++;
printf("%d\n",ans);
}
return ;
}

FZU2181+poj2942(点双连通+判奇圈)的更多相关文章

  1. poj 2942(点双连通+判奇圈)

    题目链接:http://poj.org/problem?id=2942 思路:我们对于那些相互不憎恨的骑士连边,将每次参加会议的所有人(不一定是整个骑士团,只需人数>=3且为奇数)看做一个点双联 ...

  2. loj 1300( 边双联通 + 判奇圈 )

    题目链接:http://acm.hust.edu.cn/vjudge/problem/viewProblem.action?id=27010 思路:首先Tarjan标记桥,然后对于dfs遍历整个图,我 ...

  3. fzu2181(点的双连通分量+求奇环)

    求出每个点双连通分量,如果在一个点双连通分量中有奇环,则这个分量每个点都在一个奇环中.  关键是要知道怎么求点双连通分量以及点双连通的性质. fzu2181 http://acm.fzu.edu.cn ...

  4. 图论之tarjan真乃神人也,强连通分量,割点,桥,双连通他都会

    先来%一下Robert Tarjan前辈 %%%%%%%%%%%%%%%%%% 然后是热情感谢下列并不止这些大佬的博客: 图连通性(一):Tarjan算法求解有向图强连通分量 图连通性(二):Tarj ...

  5. hdu 4598 Difference(奇圈判定+差分约束)

    这是通化邀请赛的题,当时比赛的时候还完全没想法呢,看来这几个月的训练还是有效果的... 题意要求(1) |ai| < T for all i   (2) (vi, vj) in E <=& ...

  6. POJ2942 Knights of the Round Table 点双连通分量,逆图,奇圈

    题目链接: poj2942 题意: 有n个人,能够开多场圆桌会议 这n个人中,有m对人有仇视的关系,相互仇视的两人坐在相邻的位置 且每场圆桌会议的人数仅仅能为奇书 问有多少人不能參加 解题思路: 首先 ...

  7. 【POJ 2942】Knights of the Round Table(双联通分量+染色判奇环)

    [POJ 2942]Knights of the Round Table(双联通分量+染色判奇环) Time Limit: 7000MS   Memory Limit: 65536K Total Su ...

  8. lightoj 1300 边双联通分量+交叉染色求奇圈

    题目链接:http://lightoj.com/volume_showproblem.php?problem=1300 边双连通分量首先dfs找出桥并标记,然后dfs交叉着色找奇圈上的点.这题只要求在 ...

  9. 图的强连通&双连通

    http://www.cnblogs.com/wenruo/p/4989425.html 强连通 强连通是指一个有向图中任意两点v1.v2间存在v1到v2的路径及v2到v1的路径. dfs遍历一个图, ...

随机推荐

  1. Swift - 使用Media Player播放本地视频,在线视频

    Media Player框架用于播放本地视频.音频,也可以在线播放视频和音频. 1,播放器MPMovieControlStyle样式有如下几种: (1)None: 没有播放控制控件 (2)Embedd ...

  2. <转载>DIV+CSS position定位方法总结

    如何学习DIV+CSS布局之position属性 如果用position来布局页面,父级元素的position属性必须为relative,而定位于父级内部某个位置的元素,最好用 absolute. 任 ...

  3. perl 匿名函数传参

    $subref=sub { my $a=shift; return $a; }; print $subref->("xxyyzz");

  4. 云计算Docker全面项目实战(Maven+Jenkins、日志管理ELK、WordPress博客镜像)

    2013年,云计算领域从此多了一个名词“Docker”.以轻量著称,更好的去解决应用打包和部署.之前我们一直在构建Iaas,但通过Iaas去实现统一功  能还是相当复杂得,并且维护复杂.将特殊性封装到 ...

  5. UVA 10201 Adventures in Moving - Part IV(dp)

    Problem A: Adventures in Moving - Part IV To help you move from Waterloo to the big city, you are co ...

  6. 用angularjs开发下一代web应用(二):angularjs应用骨架(二)

    1.浅谈非入侵式JavaScript <div ng-click="doSomething()">...</div>这些指令和原来的事件处理器有下面不同之处 ...

  7. android布局margin和padding差异!

    事实上从使用的时候就能够差别开来. android:padding android:layout_margin padding是在本控件级别的,而margin是在layout级别的. 最好拿有背景的控 ...

  8. MSSQL - 用GUID值来完成数据表行标识

    地址:http://www.cnblogs.com/huangfr/archive/2012/03/28/2420780.html [Guid] [uniqueidentifier] NOT NULL ...

  9. 理清JavaScript正则表达式

    理清JavaScript正则表达式--下篇 紧接:"理清JavaScript正则表达式--上篇". 正则在String类中的应用 类String支持四种利用正则表达式的方法.分别是 ...

  10. C++,Python,Go对照学习-02

    main函数         Go中有且只有一个main函数,而且main函数必须在package main当中.main函数无返回值也无参数,如果希望获取从命令行传递的参数有其他包解决这个问题.   ...