http://poj.org/problem?id=2942

题意 :n个骑士举行圆桌会议,每次会议应至少3个骑士参加,且相互憎恨的骑士不能坐在圆桌旁的相邻位置。如果意见发生分歧,则需要举手表决,因此参加会议的骑士数目必须是奇数,以防止赞同和反对的票一样多,知道哪些骑士相互憎恨之后,你的任务是统计有多少个骑士不可能参加任何一个会议。

思路 :这个题牵扯的知识点挺多的,具体的可以参考白书上解释的蛮详细的。

#include <iostream>
#include <stdio.h>
#include <stack>
#include <string.h>
#include <algorithm>
#include <vector> using namespace std;
const int maxn = ; struct Edge
{
int u,v ;
Edge(int u ,int v):u(u),v(v) {}
} ; int pre[maxn],dfs_clock ,iscut[maxn],Bcc_cnt,Bccno[maxn] ;
vector<int>G[maxn],Bcc[maxn] ;
stack<Edge>S ;
int odd[maxn],color[maxn] ;
int A[maxn][maxn] ; int dfs(int u,int fa)
{
int lowu = pre[u] = ++dfs_clock ;
int child = ;
for(int i = ; i < G[u].size() ; i++)
{
int v = G[u][i] ;
Edge e = (Edge)
{
u,v
} ;
if(!pre[v])
{
S.push(e) ;
child++ ;
int lowv = dfs(v,u) ;
lowu = min(lowu,lowv) ;
if(lowv >= pre[u])
{
iscut[u] = true ;
Bcc_cnt++ ;
Bcc[Bcc_cnt].clear() ;
for( ; ; )
{
Edge x = S.top() ;
S.pop() ;
if(Bccno[x.u] != Bcc_cnt)
{
Bcc[Bcc_cnt].push_back(x.u) ;
Bccno[x.u] = Bcc_cnt ;
}
if(Bccno[x.v] != Bcc_cnt)
{
Bcc[Bcc_cnt].push_back(x.v) ;
Bccno[x.v] = Bcc_cnt ;
}
if(x.u == u && x.v == v) break ;
}
}
}
else if(pre[v] < pre[u] && v != fa)
{
S.push(e) ;
lowu = min(lowu,pre[v]) ;
}
}
if(fa < && child == )
iscut[u] = ;
return lowu ;
} void find_Bcc(int n)
{
memset(pre,,sizeof(pre)) ;
memset(iscut,,sizeof(iscut)) ;
memset(Bccno,,sizeof(Bccno)) ;
dfs_clock = Bcc_cnt = ;
for(int i = ; i < n ; i++)
if(!pre[i])
dfs(i,-) ;
} bool bipartite(int u,int b)
{
for(int i = ; i < G[u].size() ; i++)
{
int v = G[u][i] ;
if(Bccno[v] != b)
continue ;
if(color[v] == color[u]) return false ;
if(!color[v])
{
color[v] = -color[u] ;
if(!bipartite(v,b))
return false ;
}
}
return true ;
} int main()
{
int kase = ,n,m ;
while(scanf("%d %d",&n,&m) == && n)
{
for(int i = ; i < n ; i++ )
G[i].clear() ;
memset(A,,sizeof(A)) ;
for(int i = ; i < m ; i++)
{
int u,v ;
scanf("%d %d",&u,&v) ;
u-- ;
v-- ;
A[u][v] = A[v][u] = ;
}
for(int u = ; u < n ; u++)
{
for(int v = u+ ; v < n ; v++)
if(!A[u][v])
{
G[u].push_back(v);
G[v].push_back(u) ;
}
}
find_Bcc(n) ;
memset(odd,,sizeof(odd)) ;
for(int i = ; i <= Bcc_cnt ; i++)
{
memset(color,,sizeof(color)) ;
for(int j = ; j < Bcc[i].size() ; j++)
Bccno[Bcc[i][j]] = i ;
int u = Bcc[i][] ;
color[u] = ;
if(!bipartite(u,i))
for(int j = ; j < Bcc[i].size() ; j++)
odd[Bcc[i][j]] = ;
}
int ans = n ;
for(int i = ; i < n ; i++)
if(odd[i]) ans-- ;
printf("%d\n",ans) ;
}
return ;
}

POJ 2942 Knights of the Round Table(双连通分量)的更多相关文章

  1. POJ 2942 Knights of the Round Table 黑白着色+点双连通分量

    题目来源:POJ 2942 Knights of the Round Table 题意:统计多个个骑士不能參加随意一场会议 每场会议必须至少三个人 排成一个圈 而且相邻的人不能有矛盾 题目给出若干个条 ...

  2. poj 2942 Knights of the Round Table 圆桌骑士(双连通分量模板题)

    Knights of the Round Table Time Limit: 7000MS   Memory Limit: 65536K Total Submissions: 9169   Accep ...

  3. poj 2942 Knights of the Round Table - Tarjan

    Being a knight is a very attractive career: searching for the Holy Grail, saving damsels in distress ...

  4. POJ 2942 Knights of the Round Table

    Knights of the Round Table Time Limit: 7000MS   Memory Limit: 65536K Total Submissions: 10911   Acce ...

  5. POJ 2942 Knights of the Round Table - from lanshui_Yang

    Description Being a knight is a very attractive career: searching for the Holy Grail, saving damsels ...

  6. poj 2942 Knights of the Round Table(点双连通分量+二分图判定)

    题目链接:http://poj.org/problem?id=2942 题意:n个骑士要举行圆桌会议,但是有些骑士相互仇视,必须满足以下两个条件才能举行: (1)任何两个互相仇视的骑士不能相邻,每个骑 ...

  7. POJ 2942 Knights of the Round Table (点双连通分量)

    题意:多个骑士要开会,3人及以上才能凑一桌,其中部分人已经互相讨厌,肯定不坐在同一桌的相邻位置,而且一桌只能奇数个人才能开台.给出多个人的互相讨厌图,要求多少人开不成会(注:会议不要求同时进行,一个人 ...

  8. POJ 2942.Knights of the Round Table (双连通)

    简要题解: 意在判断哪些点在一个图的  奇环的双连通分量内. tarjan求出所有的点双连通分量,再用二分图染色判断每个双连通分量是否形成了奇环,记录哪些点出现在内奇环内 输出没有在奇环内的点的数目 ...

  9. POJ - 2942 Knights of the Round Table (点双联通分量+二分图判定)

    题意:有N个人要参加会议,围圈而坐,需要举手表决,所以每次会议都必须是奇数个人参加.有M对人互相讨厌,他们的座位不能相邻.问有多少人任意一场会议都不能出席. 分析:给出的M条关系是讨厌,将每个人视作点 ...

  10. poj 2942 Knights of the Round Table(无向图的双连通分量+二分图判定)

    #include<cstdio> #include<cstring> #include<cmath> #include<cstdlib> #includ ...

随机推荐

  1. sql查询某段时间内的数据

    查询半小时内数据的方法 1.select * from 表名 where datediff(minute,createtime,getdate())<30 2.select * from 表名 ...

  2. SqlServer2005安装错误解决方法

    前段时间在安装数据库SQL Server2005时,在系统检测这一步计算机报了一个错误,提示“性能监视器计数要求(错误)”,使得安装无法继续进行,于是在网上找了些方法来解决,其中有一个方法最有效,在这 ...

  3. 通过Workbook类 生成Excel导出数据

    需求: 实现错误信息生成Excel保存到本地让用户查看. 刚开始使用了微软自带的Microsoft.Office.Interop.Excel类库. Microsoft.Office.Interop.E ...

  4. phpize php扩展模块安装

    安装(fastcgi模式)的时候,常常有这样一句命令:/usr/local/webserver/php/bin/phpize一.phpize是干嘛的?phpize是什么东西呢?php官方的说明:htt ...

  5. C# IO操作(二)File类和Directory类的常用方法

    本篇主要介绍一些常用的IO操作,对文件和目录的操作:留给自己复习之用. 1.创建文件 string sPath1=Path.GetDirectoryName(Assembly.GetExecuting ...

  6. ###STL学习--标准模板库

    下面进行STL的学习.希望能了解标准模板库中的常用容器,迭代器,可以自由运用STL以提高编写代码的效率.下面的内容我想以知识点为总结,不再像<Effective C++>那样以章节进行总结 ...

  7. java异常练习2

    /*有一个圆形和长方形都可以获取面积,对于面积,如果出现非法数值,视为获取面积出现问题问题通过异常来表示.先要对这个程序进行基本的设置 *//*首先想一下,怎么写这个程序基本属性是肯定要的求面积呢?1 ...

  8. 13_CXF和Spring整合发布服务

    [服务端] 第一步:建立一个Web项目 第二步:填充CXF jar包 第三步:创建接口及服务类 [工程截图(对比之前的WebService_CXF_Server00)] [applicationCon ...

  9. springmvc学习(三)

    第一点---------使用 @RequestMapping 映射请求• Ant 风格资源地址支持 3 种匹配符:?:匹配文件名中的一个字符 *:匹配文件名中的任意字符 **:** 匹配多层路径 @R ...

  10. iOS 构造方法

    构造方法:用于在对象创建出来的时候为对象的成员变量或者属性赋值 1.构造方法就是初始化对象的方法,它属于对象方法.构造方法分为系统自带和自定义构造方法. 如何创建自定义构造方法: 属于对象方法那么以  ...