FZU2181+poj2942(点双连通+判奇圈)
分析:我们对于那些相互不憎恨的人连边,将每次参加会议的所有人(不一定是全部人,只需人数>=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(点双连通+判奇圈)的更多相关文章
- poj 2942(点双连通+判奇圈)
题目链接:http://poj.org/problem?id=2942 思路:我们对于那些相互不憎恨的骑士连边,将每次参加会议的所有人(不一定是整个骑士团,只需人数>=3且为奇数)看做一个点双联 ...
- loj 1300( 边双联通 + 判奇圈 )
题目链接:http://acm.hust.edu.cn/vjudge/problem/viewProblem.action?id=27010 思路:首先Tarjan标记桥,然后对于dfs遍历整个图,我 ...
- fzu2181(点的双连通分量+求奇环)
求出每个点双连通分量,如果在一个点双连通分量中有奇环,则这个分量每个点都在一个奇环中. 关键是要知道怎么求点双连通分量以及点双连通的性质. fzu2181 http://acm.fzu.edu.cn ...
- 图论之tarjan真乃神人也,强连通分量,割点,桥,双连通他都会
先来%一下Robert Tarjan前辈 %%%%%%%%%%%%%%%%%% 然后是热情感谢下列并不止这些大佬的博客: 图连通性(一):Tarjan算法求解有向图强连通分量 图连通性(二):Tarj ...
- hdu 4598 Difference(奇圈判定+差分约束)
这是通化邀请赛的题,当时比赛的时候还完全没想法呢,看来这几个月的训练还是有效果的... 题意要求(1) |ai| < T for all i (2) (vi, vj) in E <=& ...
- POJ2942 Knights of the Round Table 点双连通分量,逆图,奇圈
题目链接: poj2942 题意: 有n个人,能够开多场圆桌会议 这n个人中,有m对人有仇视的关系,相互仇视的两人坐在相邻的位置 且每场圆桌会议的人数仅仅能为奇书 问有多少人不能參加 解题思路: 首先 ...
- 【POJ 2942】Knights of the Round Table(双联通分量+染色判奇环)
[POJ 2942]Knights of the Round Table(双联通分量+染色判奇环) Time Limit: 7000MS Memory Limit: 65536K Total Su ...
- lightoj 1300 边双联通分量+交叉染色求奇圈
题目链接:http://lightoj.com/volume_showproblem.php?problem=1300 边双连通分量首先dfs找出桥并标记,然后dfs交叉着色找奇圈上的点.这题只要求在 ...
- 图的强连通&双连通
http://www.cnblogs.com/wenruo/p/4989425.html 强连通 强连通是指一个有向图中任意两点v1.v2间存在v1到v2的路径及v2到v1的路径. dfs遍历一个图, ...
随机推荐
- URAL 1707. Hypnotoad's Secret(树阵)
URAL 1707. Hypnotoad's Secret space=1&num=1707" target="_blank" style="" ...
- 问题:Excel在“xxx.xlsx”中发现不可读取的内容。是否恢复此工作薄的内容?【原创】
现象: 点"是(Y)" 提示信息中提到的error242440_02.xml文件: 问题重现: package poi; import java.io.FileNotFoundEx ...
- 安卓开发23:Service详细解读
关于Service Service说明:Service是android 系统中的四大组件之一(Activity.Service.BroadcastReceiver.ContentProvider),它 ...
- 使用hadoop ecipse插件须要注意的问题
1.关于run on hadoop的问题: 在未用hadoop eclipse插件前,我以为通过hadoop eclipse 插件不但能够管理hdfs,还能够自己主动打包程序.并帮我自己主动设置Con ...
- Effective C++_笔记_条款12_复制对象时勿忘其每一个成分
(整理自Effctive C++,转载请注明.整理者:华科小涛@http://www.cnblogs.com/hust-ghtao/) 编译器会在必要时候为我们的classes创建copying函数, ...
- 老罗android开发视频教程 下载地址
感觉老罗android开发视频教程讲得挺好挺全面的,适合新手学习.分享 老罗android开发视频教程 下载地址: 电驴:http://www.verycd.com/topics/2929580/ 老 ...
- 显示器 Linux 性能 18 (一个命令行工具传递)
对于系统和网络管理员来说每天监控和调试Linux系统的性能问题是一项繁重的工作.在IT领域作为一名Linux系统的管理员工作5年后,我逐渐认识到监控和保持系统启动并执行是多么的不easy.基于此原因. ...
- 根据图像路径,创建CBitmap对象的方法
因为项目的关系,需要根据图像路径,创建CBitmap对象.起初查资料找到了LoadBitmap这个函数,根据CSDN得 BOOL LoadBitmap ( LPCTSTR lpszResourceNa ...
- form表单提交不成功提示
<!DOCTYPE html> <html lang="zh-CN"> <head> <meta charset="utf-8& ...
- Qt之VLFeat SLIC超像素分割(Cpp版)
源地址:http://yongyuan.name/blog/vlfeat-slic-with-qt.html 近段时间学了点Qt,恰好前段时间用借助VLfeat以及OpenCV捣鼓了SLIC超像素分割 ...