Knights of the Round Table

Description

Being a knight is a very attractive career: searching for the Holy Grail, saving damsels in distress, and drinking with the other knights are fun things to do. Therefore, it is not very surprising that in recent years the kingdom of King Arthur has experienced
an unprecedented increase in the number of knights. There are so many knights now, that it is very rare that every Knight of the Round Table can come at the same time to Camelot and sit around the round table; usually only a small group of the knights isthere,
while the rest are busy doing heroic deeds around the country. 



Knights can easily get over-excited during discussions-especially after a couple of drinks. After some unfortunate accidents, King Arthur asked the famous wizard Merlin to make sure that in the future no fights break out between the knights. After studying
the problem carefully, Merlin realized that the fights can only be prevented if the knights are seated according to the following two rules:

  • The knights should be seated such that two knights who hate each other should not be neighbors at the table. (Merlin has a list that says who hates whom.) The knights are sitting around a roundtable, thus every knight has exactly two neighbors.
  • An odd number of knights should sit around the table. This ensures that if the knights cannot agree on something, then they can settle the issue by voting. (If the number of knights is even, then itcan happen that ``yes" and ``no" have the same number of
    votes, and the argument goes on.)

Merlin will let the knights sit down only if these two rules are satisfied, otherwise he cancels the meeting. (If only one knight shows up, then the meeting is canceled as well, as one person cannot sit around a table.) Merlin realized that this means that
there can be knights who cannot be part of any seating arrangements that respect these rules, and these knights will never be able to sit at the Round Table (one such case is if a knight hates every other knight, but there are many other possible reasons).
If a knight cannot sit at the Round Table, then he cannot be a member of the Knights of the Round Table and must be expelled from the order. These knights have to be transferred to a less-prestigious order, such as the Knights of the Square Table, the Knights
of the Octagonal Table, or the Knights of the Banana-Shaped Table. To help Merlin, you have to write a program that will determine the number of knights that must be expelled. 


Input

The input contains several blocks of test cases. Each case begins with a line containing two integers 1 ≤ n ≤ 1000 and 1 ≤ m ≤ 1000000 . The number n is the number of knights. The next m lines describe which knight hates which knight. Each of these m lines
contains two integers k1 and k2 , which means that knight number k1 and knight number k2 hate each other (the numbers k1 and k2 are between 1 and n ). 



The input is terminated by a block with n = m = 0 . 


Output

For each test case you have to output a single integer on a separate line: the number of knights that have to be expelled. 


Sample Input

5 5
1 4
1 5
2 5
3 4
4 5
0 0

Sample Output

2

Hint

Huge input file, 'scanf' recommended to avoid TLE. 

Source


题意:


由于无视武士之间容易打架,Merlin智者为了发生武士打架,有两个规则:
(1):相互仇视的武士不能挨着做,由于是坐在圆桌周围,每一个武士有两个相邻的武士。
(2):围着圆桌做的武士数目必须是奇数个,以确保在发生问题时,能够投票解决。
满足以上两个条件的武士可以坐下来,如果一个武士不可能被安排坐下,他将被从武士的名单中去除。
智者想知道有多少武士将被去除。

方法:
构造无向图,将不相互仇视的建立边。

(1):搜索双连通分量。DFS过程中,用一个栈保存所有经过的点,判断割点,碰到割点就将标记栈的顶点并退栈,直到当前节点停止标记当前割点。标记过的节点在同一个连通分量里。
(2):交叉染色搜索奇偶。在一个节点大于2的双连通分量中,必定存在一个圈经过所有的节点,如果这个圈是奇圈,则该连通分量的所有点都满足,如果是偶圈,如果包含奇圈,必定还有一个奇圈经过剩余的所有节点,因此一个双连通分量里只要存在一个奇圈。
(3):一个点可能满足多个连通分量

#include <cstdio>
#include <cstring>
#include <queue>
#include <stack>
#include <vector>
#include <set>
#include <map>
#include <cmath>
#include <cstdlib>
#include <algorithm>
#define LL long long using namespace std; const int Max = 1100; typedef struct Node
{
int num; int next;
}Line; Line Li[Max*100]; int top; int Head[Max]; int low[Max],dfn[Max]; int Map[Max][Max]; int n,m; int Num,num,ant; int Que[Max]; int vis[Max]; int part[Max],color[Max]; void AddNum(int u)
{
Li[top].num=num;
Li[top].next = Head[u];
Head[u] = top++;
} void dfs(int u,int father)
{
vis[u]=1;//表示正在访问 dfn[u]=low[u]=Num++; Que[ant++]=u; for(int i=1;i<=Map[u][0];i++)
{
if(vis[Map[u][i]]==1&&Map[u][i]!=father)
{
low[u]=min(low[u],dfn[Map[u][i]]);
}
if(vis[Map[u][i]]==0)
{
dfs(Map[u][i],u); low[u]=min(low[Map[u][i]],low[u]); if(low[Map[u][i]]>=dfn[u])//子树形成环
{
// 标记
AddNum(u); for(int j=Que[ant];j!=Map[u][i];AddNum(j))
{
j=Que[--ant];
} num++ ;
}
}
} vis[u]=2;//表示已经访问并且处理完
} int OddCycle(int u,int flag)//判断奇环
{
color[u]=flag; for(int i=1;i<=Map[u][0];i++)
{
if(!part[Map[u][i]])
{
continue;
} if(color[Map[u][i]]==0 && OddCycle(Map[u][i],-flag))
{
return 1;
}
if(color[Map[u][i]]==flag)
{
return 1;
}
}
return 0;
} int main()
{
int u,v; while(~scanf("%d %d",&n,&m)&&(n+m))
{ // 数据处理
memset(Map,0,sizeof(Map)); for(int i=1;i<=m;i++)
{
scanf("%d %d",&u,&v); Map[u][v]=Map[v][u]=1;
} for(int i=1;i<=n;i++)
{
Map[i][i]=1;
}
//建图
for(int i=1;i<=n;i++)
{
for(int j=1;j<=n;j++)
{
Map[0][j]=Map[i][j];
} for(int j=1;j<=n;j++)
{
if(!Map[0][j])
Map[i][++Map[i][0]]=j;
}
} memset(vis,0,sizeof(vis)); // 标记是否被访问,以及访问的状态 memset(Head,-1,sizeof(Head)); Num = 0; num=0 ; top=0;ant = 0; //去除割边 for(int i=1;i<=n;i++)
{
if(!vis[i])
{
Num = 0;
dfs(i,0);
}
} memset(vis,0,sizeof(vis)); for(int i=0;i<num;i++)//判断奇环
{ memset(part,0,sizeof(part)); memset(color,0,sizeof(color)); for(int j=1;j<=n;j++)
{
for(int k=Head[j];k!=-1;k=Li[k].next)
{
if(Li[k].num == i)
{
part[j]=1;
break;
}
}
} for(int j=1;j<=n;j++)
{
if(part[j])
{
if(OddCycle(j,1))
{
for(int k=1;k<=n;k++)
{
vis[k]+=part[k];
}
}
break;
}
}
} int ans = 0; for(int i=1;i<=n;i++)
{
if(!vis[i])
{
ans++;
}
} printf("%d\n",ans);
}
return 0;
}

Knights of the Round Table-POJ2942(双连通分量+交叉染色)的更多相关文章

  1. POJ2942 Knights of the Round Table[点双连通分量|二分图染色|补图]

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

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

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

  3. 【POJ】2942 Knights of the Round Table(双连通分量)

    http://poj.org/problem?id=2942 各种逗.... 翻译白书上有:看了白书和网上的标程,学习了..orz. 双连通分量就是先找出割点,然后用个栈在找出割点前维护子树,最后如果 ...

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

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

  5. POJ2942 Knights of the Round Table 点双连通分量 二分图判定

    题目大意 有N个骑士,给出某些骑士之间的仇恨关系,每次开会时会选一些骑士开,骑士们会围坐在一个圆桌旁.一次会议能够顺利举行,要满足两个条件:1.任意相互憎恨的两个骑士不能相邻.2.开会人数为大于2的奇 ...

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

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

  7. UVALive-3523 Knights of the Round Table (双连通分量+二分图匹配)

    题目大意:有n个骑士要在圆桌上开会,但是相互憎恶的两个骑士不能相邻,现在已知骑士们之间的憎恶关系,问有几个骑士一定不能参加会议.参会骑士至少有3个且有奇数个. 题目分析:在可以相邻的骑士之间连一条无向 ...

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

    http://poj.org/problem?id=2942 题意 :n个骑士举行圆桌会议,每次会议应至少3个骑士参加,且相互憎恨的骑士不能坐在圆桌旁的相邻位置.如果意见发生分歧,则需要举手表决,因此 ...

  9. [POJ2942]Knights of the Round Table(点双+二分图判定——染色法)

    建补图,是两个不仇恨的骑士连边,如果有环,则可以凑成一桌和谐的打麻将 不能直接缩点,因为直接缩点求的是连通分量,点双缩点只是把环缩起来 普通缩点                             ...

随机推荐

  1. HTML input文本框设置和移除默认值

    这里想实现的效果是:设置和移除文本框默认值,如下图鼠标放到文本框中的时候,灰字消失. 1.可以用简单的方式,就是给input文本框加上onfocus属性,如下代码: <input id=&quo ...

  2. Java可读取操作系统的配置

    /** * Java获取操作系统的配置环境 * @throws Exception */ @Test public void testPro() throws Exception { Properti ...

  3. centos6.6 LVS+keepalived

    之前有写过keepalived+mysql  和lvsDR模式的分析篇.然而LVS没有写高冗余.今天来写一篇LVS+keepalived的 LVSDR只负责转发,LVS也没有nginx后端检查功能,所 ...

  4. SQL Server如何添加登录名

    1.电脑上如果安装有SQL Server,我们在开始里面打开SQL Server Management Studio,或者以桌面的快捷方式等打开SQL Server. 2.首先以Windows身份验证 ...

  5. 数的长度---nyoj69

    超时 #include <stdio.h>#include <string.h>#define M 1000001int shu[M]; int main(){ int n, ...

  6. 数据库---MySQL常用函数总结

    一.数学函数 数学函数主要用于处理数字,包括整型.浮点数等. ABS(x)    返回x的绝对值 SELECT ABS(-1) -- 返回1 CEIL(x),CEILING(x)    返回大于或等于 ...

  7. Mysql的常用用法

    一.mysql中limit的用法详解[数据分页常用] 在我们使用查询语句的时候,经常要返回前几条或者中间某几行数据,这个时候怎么办呢?不用担心,mysql已经为我们提供了这样一个功能. SELECT  ...

  8. java基础学习总结——基础语法1

    一.标识符

  9. Python之路-python数据类型(列表、字典、字符串、元祖)操作

    一.列表: 列表的语法,以中括号开通和结尾,元素以逗号隔开.例如:name = [] 列表是以下标取值,第一个元素下标是0,第二个元素下标是1,最后一个元素下标是-1.   1.增加 #name = ...

  10. Sql用变量拼语句

    CREATE PROC Test_GetCollegeInfo @type int AS BEGIN ),@v int,@sql nvarchar(max) Begin )) END ELSE BEG ...