[POJ2942]Knights of the Round Table(点双+二分图判定——染色法)
建补图,是两个不仇恨的骑士连边,如果有环,则可以凑成一桌和谐的打麻将
不能直接缩点,因为直接缩点求的是连通分量,点双缩点只是把环缩起来
普通缩点 点双缩点
由图可知,左图中的缩法不符题意,而右图两个缩完后的点都满足题意
然后题中说必须要奇数个骑士参加会议,即找奇圈(有奇数个点的圈)
问题就转化成缩点后判断一个点是否在奇圈里,这就用到了点双的性质
点双连通分量有两个性质:1.如果该分量里有一个奇圈,那么其他所有点也必然在某个奇圈中;2.含有一个奇圈的充要条件是该分量不是二分图。
所以我们只需要缩完点之后枚举V-DCC判断是不是二分图,不是二分图就是奇圈
那么判断二分图用染色法判断即可
注意一个骑士不可以参加会议
这句话是自言自语: Lockey注意要检查变量名是否写对了
二分图定义:
一个无向图,使得顶点集V可以分割为两个互不相交的子集A,B,使得所有边两端分别属于两个子集A,B。
度娘解释
- #include<iostream>
- #include<cstdio>
- #include<vector>
- #include<cstring>
- using namespace std;
- int n,m,a[][],dfn[],low[],st[],ins[],num,v[],cnt,sp[],ok[],flag[],root;
- vector<int>son[],spn[];
- void tarjan(int x,int pre){
- dfn[x]=low[x]=++num;
- if(x==root&&son[x].size()==) spn[++cnt].push_back(x);
- st[++st[]]=x;
- ins[x]=;
- for(int i=;i<son[x].size();i++){
- int y=son[x][i];
- if(y==pre) continue;
- if(!dfn[y]){
- tarjan(y,x);
- low[x]=min(low[x],low[y]);
- if(low[y]>=dfn[x]){
- cnt++;
- int w;
- do{
- w=st[st[]--];
- ins[w]=;
- spn[cnt].push_back(w);
- }while(w!=y);
- spn[cnt].push_back(x);
- }
- }
- else low[x]=min(low[x],dfn[y]);
- }
- }
- int dfs(int x,int pre,int loc){//是二分图返回0,是奇圈返回1
- v[x]=v[pre]^;
- //cout<<x<<" "<<v[x]<<endl;
- for(int i=;i<son[x].size();i++){
- int y=son[x][i];
- //cout<<y<<" "<<" "<<flag[y]<<" "<<v[y]<<endl;
- if(!flag[y]||y==pre) continue;
- if(v[y]==-){
- if(dfs(y,x,loc)) return ;
- }
- else if(v[y]==v[x]) return ;
- }
- return ;
- }
- int main(){
- scanf("%d%d",&n,&m);
- while(n!=||m!=){
- int x,y;
- for(int i=;i<=m;i++){
- scanf("%d%d",&x,&y);
- a[x][y]=a[y][x]=;
- }
- for(int i=;i<=n;i++){
- for(int j=;j<=n;j++){
- if(a[i][j]||i==j) continue;
- son[i].push_back(j);
- }
- }
- for(int i=;i<=n;i++){
- if(!dfn[i]) root=i,tarjan(i,);
- }
- memset(v,-,sizeof(v));
- v[]=;
- //cout<<cnt<<endl;
- for(int i=;i<=cnt;i++){
- if(spn[i].size()==) continue;
- for(int j=;j<spn[i].size();j++) flag[spn[i][j]]=;
- if(dfs(spn[i][],,i))
- for(int j=;j<spn[i].size();j++)
- ok[spn[i][j]]=;
- for(int j=;j<spn[i].size();j++) flag[spn[i][j]]=,v[spn[i][j]]=-;
- }
- int ans=;
- for(int i=;i<=n;i++) ans+=ok[i];
- printf("%d\n",n-ans);
- for(int i=;i<=n;i++){
- dfn[i]=low[i]=;
- st[i]=;
- ins[i]=;
- ok[i]=;
- sp[i]=;
- son[i].clear();
- spn[i].clear();
- }
- st[]=;
- memset(v,-,sizeof(v));
- memset(a,,sizeof(a));
- num=cnt=;
- scanf("%d%d",&n,&m);
- }
- }
[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(双联通分量+染色判奇环) Time Limit: 7000MS Memory Limit: 65536K Total Su ...
- POJ2942 Knights of the Round Table[点双连通分量|二分图染色|补图]
Knights of the Round Table Time Limit: 7000MS Memory Limit: 65536K Total Submissions: 12439 Acce ...
- POJ2942 Knights of the Round Table 点双连通分量 二分图判定
题目大意 有N个骑士,给出某些骑士之间的仇恨关系,每次开会时会选一些骑士开,骑士们会围坐在一个圆桌旁.一次会议能够顺利举行,要满足两个条件:1.任意相互憎恨的两个骑士不能相邻.2.开会人数为大于2的奇 ...
- [POJ2942]:Knights of the Round Table(塔尖+二分图染色法)
题目传送门 题目描述 亚瑟王要在圆桌上召开骑士会议,为了不引发骑士之间的冲突,并且能够让会议的议题有令人满意的结果,每次开会前都必须对出席会议的骑士有如下要求: .相互憎恨的两个骑士不能坐在直接相邻的 ...
- POJ2942 Knights of the Round Table 点双连通分量,逆图,奇圈
题目链接: poj2942 题意: 有n个人,能够开多场圆桌会议 这n个人中,有m对人有仇视的关系,相互仇视的两人坐在相邻的位置 且每场圆桌会议的人数仅仅能为奇书 问有多少人不能參加 解题思路: 首先 ...
- 【POJ】2942 Knights of the Round Table(双连通分量)
http://poj.org/problem?id=2942 各种逗.... 翻译白书上有:看了白书和网上的标程,学习了..orz. 双连通分量就是先找出割点,然后用个栈在找出割点前维护子树,最后如果 ...
- 「题解」:[POJ2942]Knights of the Round Table
问题 E: Knights of the Round Table 时间限制: 1 Sec 内存限制: 256 MB 题面 题目描述 作为一名骑士是一个非常有吸引力的职业:寻找圣杯,拯救遇难的少女,与 ...
- Knights of the Round Table-POJ2942(双连通分量+交叉染色)
Knights of the Round Table Description Being a knight is a very attractive career: searching for the ...
随机推荐
- Fabric-Crashlytics-Android 注意点
Fabric-Crashlytics-Android 注意点 非发布版本关闭Fabirc 官方文档中有这方面的介绍,有助于在开发过程中,提高编译速度和避免上报不必要的Crash 链接 一共两步 第一步 ...
- Struts2之Struts2
Struts2-2.5.5版本是目前为止最新的版本了,相对于之前的2.3版本以及再之前的版本而言,新版本改动了很多. 好了,废话不多说,GO CODE! 基本jar包: web.xml核心配置,这里要 ...
- EPPlus导出两千万行记录到xlsx的c#代码
private void button5_Click(object sender, EventArgs e) { Stopwatch watch = new Stopwatch(); Backgrou ...
- 【转】python Counter模块
>>> c = Counter() # 创建一个新的空counter >>> c = Counter('abcasdf') # 一个迭代对象生成的counter & ...
- WPF 用Main函数方式启动程序
原文:WPF 用Main函数方式启动程序 WPF默认程序启动:新建project后自动生成的App.xaml中指定程序启动方式(StartupUri="MainWindow.xaml&quo ...
- hadoop(三)
hadoop(三) 1.对MapReduce的认识 MapReduce是运行在yarn上面的一个分布式运算框架,它是用来解决海量的分布式运算的.对于MapReduce来说,我们可以把它分成两部分来 ...
- Delphi的对象注销方法Destroy和free
当您使用完对象后,您应该及时撤销它,以便把这个对象占用的内存释放出来.您可以通过调用一个注销方法来撤销您的对象,它会释放分配给这个对象的内存. Delphi的注销方法有两个:Destroy和Free. ...
- SSL Converter & Formats
https://www.sslshopper.com/ssl-converter.html PEM Format The PEM format is the most common format th ...
- Sailfish OS 2.1.0 发布,带来重大的架构变化
Sailfish OS 2.1.0 Iijoki 发布了. Iijoki通过引入Qt 5.6 UI框架.BlueZ 5 蓝牙堆栈和 64 位架构的基本实现,为Sailfish操作系统带来了重大的架构变 ...
- C C++ Java C# JS编译、执行过程的原理入门分析
C.C++是典型的编译型编程语言,编译链接后,点击则可执行. JS,解释型脚本语言,则不需要进行编译,直接解释执行. Java和C#则是所谓的高级语言,编译执行的方式做了很多处理, 尤其是C#,VS编 ...