题目来源:POJ 2942 Knights of the Round Table

题意:统计多个个骑士不能參加随意一场会议 每场会议必须至少三个人 排成一个圈 而且相邻的人不能有矛盾 题目给出若干个条件表示2个人直接有矛盾

思路:求补图  能够坐在一起 就是能够相邻的人建一条边 然后假设在一个奇圈上的都是满足的 那些不再不论什么一个奇圈的就是不满足 求出全部奇圈上的点 总数减去它就是答案

首先有2个定理

1.一个点双连通分量是二分图 你就没有奇圈 假设有奇圈  那就不是二分图  充分必要条件 所以

2.一个点双连通分量有奇圈  那这个点双连通分量全部点都在奇圈上

所以这题就求点双连通分量 然后对每一个分量进行二分图判定 不是二分图 就把该双连通分量全部点都标记  标记是由于一个割点可能属于多个双连通分量

所以标记在求和

#include <vector>
#include <cstdio>
#include <cstring>
#include <stack>
#include <algorithm>
using namespace std;
const int maxn = 1010;
struct Edge
{
int u, v;
Edge(){}
Edge(int u, int v): u(u), v(v){}
};
vector <int> a[maxn];
vector <int> bcc[maxn];
int pre[maxn];
int low[maxn];
int bccno[maxn];
int dfs_clock;
int bcc_cnt;
int bri;
int n, m;
int degree[maxn];
stack <int> S;
int A[maxn][maxn];
int odd[maxn];
int color[maxn];
bool bipartite(int u, int b)
{
for(int i = 0; i < a[u].size(); i++)
{
int v = a[u][i];
if(bccno[v] != b)
continue;
if(color[u] == color[v])
return false;
if(!color[v])
{
color[v] = 3 - color[u];
if(!bipartite(v, b))
return false;
}
}
return true;
}
void dfs(int u, int fa)
{
low[u] = pre[u] = ++dfs_clock;
S.push(u);
for(int i = 0; i < a[u].size(); i++)
{
int v = a[u][i];
if(v == fa)
continue;
if(!pre[v])
{
dfs(v, u);
low[u] = min(low[u], low[v]);
if(pre[u] <= low[v])
{
bcc_cnt++;
while(1)
{
int x = S.top(); S.pop();
bccno[x] = bcc_cnt;
bcc[bcc_cnt].push_back(x);
if(x == v)
{
bcc[bcc_cnt].push_back(u);
break;
}
}
}
}
else if(v != fa)
low[u] = min(low[u], pre[v]);
}
/*if(low[u] == pre[u])
{
bcc_cnt++;
while(1)
{
int x = S.top(); S.pop();
bccno[x] = bcc_cnt;
bcc[bcc_cnt].push_back(x);
if(x == u)
break;
}
}*/
}
void find_bcc()
{
memset(pre, 0, sizeof(pre));
memset(bccno, 0, sizeof(bccno));
dfs_clock = bcc_cnt = bri = 0;
for(int i = 1; i <= n; i++)
if(!pre[i])
dfs(i, -1);
}
int main()
{ while(scanf("%d %d", &n, &m) && (n||m))
{
memset(A, 0, sizeof(A));
while(m--)
{
int u, v;
scanf("%d %d", &u, &v);
A[u][v] = A[v][u] = 1;
}
for(int i = 0; i <= n; i++)
{
a[i].clear();
bcc[i].clear();
}
for(int i = 1; i <= n; i++)
for(int j = i+1; j <= n; j++)
{
if(A[i][j])
continue;
a[i].push_back(j);
a[j].push_back(i);
}
find_bcc();
memset(odd, 0, sizeof(odd));
for(int i = 1; i <= bcc_cnt; i++)
{
memset(color, 0, sizeof(color));
for(int j = 0; j < bcc[i].size(); j++)
bccno[bcc[i][j]] = i;
int u = bcc[i][0];
color[u] = 1;
if(!bipartite(u, i))
{
for(int j = 0; j < bcc[i].size(); j++)
odd[bcc[i][j]] = 1;
}
}
int ans = n;
for(int i = 1; i <= n; i++)
if(odd[i])
ans--;
printf("%d\n", ans);
}
return 0;
}

POJ 2942 Knights of the Round Table 黑白着色+点双连通分量的更多相关文章

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

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

  2. 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 ...

  3. POJ 2942 Knights of the Round Table

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

  4. 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 ...

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

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

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

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

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

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

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

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

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

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

随机推荐

  1. rosbag使用--记录深度相机数据

    首先看一下教程: http://wiki.ros.org/openni_launch/Tutorials/BagRecordingPlayback 知道了rosbag如何进行使用记录深度数据 但是按照 ...

  2. mysql数据库设计之物理设计

    一.存储引擎 推荐使用Innodb,这也是mysql默认使用的存储引擎,支持事务 二.属性的选择 字符选择: 1.char,存定长,速度快,存在空间浪费的可能,会处理尾部空格,上限255字节.(utf ...

  3. portainer,用于管理docker swarm,好像也不错哟

    shipyard的模式,好像在docker 1.12之后,没有啥用武之地了,也没有更新. 接下来,集群管理和调度,最有知名度的就是rancher了. 在rancher之前,我们试一下portainer ...

  4. 在servlet中返回json数据

    在servlet: String name = new tring(request.getParameter("name").getBytes("iso8859-1&qu ...

  5. 最小生成树的Kruskal算法

        库鲁斯卡尔(Kruskal)算法是一种按照连通网中边的权值递增的顺序构造最小生成树的方法.Kruskal算法的基本思想是:假设连通网G=(V,E),令最小生成树的初始状态为只有n个顶点而无边的 ...

  6. nodejs 服务器重新启动

    在 我们开发node 应用的时候,一但你的应用已经启动了,这个时候如果你修改了服务端的文件,那么要是这个修改起作用,你必须手动停止服务然后再重新启动,这在开发过程中无 疑是很烦人的一件事,最好是有一个 ...

  7. centos6.5 python2.7.8 安装scrapy总是出错【解决】

    pip install Scrapy 报错: UnicodeDecodeError: 'ascii' codec can't decode byte 0xb4 in position python s ...

  8. Codeforces 723 A. The New Year: Meeting Friends

    A. The New Year: Meeting Friends time limit per test 1 second memory limit per test 256 megabytes in ...

  9. (13)python 正则表达式

    匹配单个字符 f. o    f和o之间是任意字符   例如:fbo123 .. 任意两个字符 \.用来匹配. 边界匹配 the     表示包含the的任何字符串 ^from 表示以from开头的所 ...

  10. circusctl命令在ubuntu 上执行,卡住的现象处理。

    1. circus介绍 circus是一个进程管理工具,类似于supervisod. 2. circusctl是circusd进程的管理工具 3. circus的安装 pip3 install cir ...