题目链接:https://vjudge.net/problem/UVA-1364

题意:有n个人参加会议,互相憎恨的人不能坐在相邻的位置,并且每个会议参加的人数必须是奇数,求有多少个人不能参加任何一个会议。

思路:如果两个人可以坐在一起,则在他们之间建立一条无向边。求不在任何一个简单奇圈上面的点的个数。简单圈上面的点必然属于同一个点双联通分量,因此首先需要找出所有的点双联通分量、因为二分图是没有奇圈的,所以需要求那些不是二分图的点双联通分量。虽然这些点双联通分量一定含有奇圈,那么是否是所有的点都在奇圈上面呢。v属于点双联通分量B,但是不在属于B的奇圈C上面。根据点双联通的性质,v一定可以到达C中的一个结点u1,v也一定可以到达C中的入一个结点u2,在C中u1到u2的两条路的长度一奇一偶,总能构建出一个奇圈。

代码:

#include<iostream>
#include<cstdio>
#include<cmath>
#include<cstring>
#include<algorithm>
#include<map>
#include<stack>
#include<vector>
using namespace std;
const int MAXN=1e3+,INF=0x3f3f3f3f,MOD=1e9+;
int n,m;
int vis[MAXN][MAXN];
vector<int>G[MAXN];
int dfs_color=; ///dfs时间戳
int pre[MAXN],post[MAXN];
int bcc_cnt=; ///联通分量
int low[MAXN]; ///u及其后代所能连回的最早祖先的pre值
int iscut[MAXN]; ///割点
vector<pair<int,int> >birdge; ///桥
struct edge
{
int u,v;
};
stack<edge>S;
int bccno[MAXN]; ///点所在的双联通分量
vector<int>bcc[MAXN]; ///双联通分量
int dfs(int u,int fa)
{
int lowu=pre[u]=++dfs_color;
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;
if(lowv>pre[u]) birdge.push_back(make_pair(u,v));
bcc_cnt++;
bcc[bcc_cnt].clear();
while(!S.empty())
{
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]=;
low[u]=lowu;
return low[u];
}
void find_bcc()
{
bcc_cnt=;
dfs_color=;
memset(pre,,sizeof(pre));
memset(iscut,,sizeof(iscut));
memset(bccno,,sizeof(bccno));
for(int i=; i<=n; i++)
if(!pre[i]) dfs(i,-);
}
void init(int n,int m)
{
memset(vis,,sizeof(vis));
for(int i=; i<=n; i++) G[i].clear();
birdge.clear();
while(m--)
{
int u,v;
scanf("%d%d",&u,&v);
vis[u][v]=vis[v][u]=;
}
for(int i=; i<=n; i++)
{
for(int j=; j<i; j++)
{
if(vis[i][j]) continue;
G[i].push_back(j);
G[j].push_back(i);
}
}
}
int color[MAXN];
int odd[MAXN];
bool bipartite(int u,int d)
{
for (int i = ; i < G[u].size(); i++)
{ int v=G[u][i];
if (bccno[v]!=d) continue;
if (color[v]==color[u]) return false;
if (!color[v])
{
color[v]=-color[u];
if (!bipartite(v,d)) return false;
}
}
return true;
}
int solve()
{
memset(odd,,sizeof(odd));
for(int i=; i<=bcc_cnt; i++)
{
for(int j=;j<bcc[i].size();j++) bccno[bcc[i][j]]=i;
memset(color,,sizeof(color));
color[bcc[i][]]=;
if(!bipartite(bcc[i][],i))
{
for (int j=; j<bcc[i].size(); j++)
odd[bcc[i][j]]=;
}
}
int ans=;
for(int i=; i<=n; i++)
if(!odd[i]) ans++;
return ans;
}
int main()
{
while(scanf("%d%d",&n,&m))
{
if(n==&&m==) break;
init(n,m);
find_bcc();
cout<<solve()<<endl;
}
return ;
}

无向图BCC+二部图

UVA-1364.Knights of the Round Table 无向图BCC的更多相关文章

  1. UVA 1364 - Knights of the Round Table (获得双连接组件 + 二部图推理染色)

    尤其是不要谈了些什么,我想A这个问题! FML啊.....! 题意来自 kuangbin: 亚瑟王要在圆桌上召开骑士会议.为了不引发骑士之间的冲突. 而且可以让会议的议题有令人惬意的结果,每次开会前都 ...

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

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

  3. uva 3523 Knights of the Round Table

    题意:给你n,m n为有多少人,m为有多少组关系,每组关系代表两人相互憎恨,问有多少个骑士不能参加任何一个会议. 白书算法指南 对于每个双联通分量,若不是二分图,就把里面的节点标记 #include ...

  4. UVAlive3523 Knights of the Round Table(bcc)

    题目链接:http://acm.hust.edu.cn/vjudge/problem/viewProblem.action?id=18122 [思路] 点-双连通分量 求出bcc,判断每个bcc是否为 ...

  5. POJ2942 UVA1364 Knights of the Round Table 圆桌骑士

    POJ2942 洛谷UVA1364(博主没有翻墙uva实在是太慢了) 以骑士为结点建立无向图,两个骑士间存在边表示两个骑士可以相邻(用邻接矩阵存图,初始化全为1,读入一对憎恨关系就删去一条边即可),则 ...

  6. POJ 2942 Knights of the Round Table

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

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

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

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

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

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

随机推荐

  1. linux下WIFI的AP搜索、连接方法

    wpa_supplicant -Dwext -ieth1 -c/etc/wpa_supplicant.conf  &wpa_cli save_configwpa_cli reconfigure ...

  2. hive 的理解

    什么是Hive 转自: https://blog.csdn.net/qingqing7/article/details/79102691 1.Hive简介 Hive 是建立在 Hadoop 上的数据仓 ...

  3. 关于WPS查看PDF文件操作问题

    自己一直使用WPS打开PDF类的文档,但是使用过程中,存在下面的几个问题: pdf 如何查看当前页码pdf 如何根据目录跳转到指定页WPS 查看pdf 如何跳转到指定页 后来百度后,可以考虑将PDF转 ...

  4. centos最小安装之后无法使用ifconfig

    Centos7安装之后,无法使用ifconfig(找不到命令) 运行 yum install provides 再安装net-tools即可 yum install net-tools 没有网,下载r ...

  5. linux上单网卡配置使用多个IP地址

    准备一台红帽系列的linux(例如rhel.red hat.centos.fredora等) 方法/步骤 新建配置文件. 首先说明一下规则: 新建配置文件,配置文件名称为ifcfg-适配器名称:0-2 ...

  6. backdoor-factory

    启动backdoor-factory 寻找大于100字节的代码洞 执行的结果 查看适合的payload程序 iat_reverse_tcp_stager_threaded分片段注入方式 使用这种注入方 ...

  7. day11 闭包函数和装饰器

    1.函数不是新知识点 主要是学习函数的用法 在面向对象编程中,一切皆对象,函数也不例外 具体的表现 1.函数可以引用 2.函数可以作为函数的参数 3.函数可以作为函数的返回值 4.可以被存储到容器类型 ...

  8. 使用Fiddler查看APP的请求接口、接口参数和返回值的方法

    1.下载Fiddler,然后安装成功后. 2.开启代理的设置 3.查看电脑的ip, 4.建立一个wifi局域网,什么360wifi,猎豹wifi,腾讯wifi都可以,用安装手机接入到这个局域网的wif ...

  9. pycharm的安装(图文)

    pycharm的安装, PyCharm是一种 IDE,可以在里面对python代码调试.语法高亮.Project管理.跳转.智能提示.自动完成.单元测试.版本控制.pycharm提供了一些高级功能,以 ...

  10. mro具体解释

    你真的理解Python中MRO算法吗? [前言] MRO(Method Resolution Order):方法解析顺序.Python语言包含了很多优秀的特性,其中多重继承就是其中之一,但是多重继承会 ...