POJ2942:Knights of the Round Table——题解
http://poj.org/problem?id=2942
所写的tarjan练习题最难的一道。
说白了难在考得不是纯tarjan。
首先我们把仇恨关系处理成非仇恨关系的图,然后找双连通分量,在双连通分量里的点满足了任意一个人可以和两个(或以上)的人坐一起。
那么我们接下来要判断奇环。
发现性质:如果一个双连通分量有奇环,那么其中任意一点一定在某个奇环上。
也就是说,这些人拼一拼绝对能全部开会成功,我们把他们打上成功标志。
然后搜失败标志的人的个数即可。
判断奇环的方法显然二分图染色。
#include<stack>
#include<cstdio>
#include<cstring>
#include<vector>
#include<iostream>
#include<algorithm>
using namespace std;
typedef long long ll;
inline int read(){
int x=,w=;char ch=;
while(ch<''||ch>''){if(ch=='-')w=-;ch=getchar();}
while(ch>=''&&ch<=''){x=(x<<)+(x<<)+ch-'';ch=getchar();}
return x*w;
}
const int maxn=;
struct node{
int st;
int to;
int nxt;
}edge[];
int cnt,head[maxn];
void add(int u,int v){
cnt++;
edge[cnt].st=u;
edge[cnt].to=v;
edge[cnt].nxt=head[u];
head[u]=cnt;
return;
}
bool dis[maxn][maxn];
bool ok[maxn];
int color[maxn];
int dfn[maxn];
int low[maxn];
bool inslt[maxn];
int t=;
int n,m;
int numslt[maxn];
stack<int>q;
vector<int>slt[maxn];
int slt_cnt;
void tarjan(int u,int f){
t++;
dfn[u]=t;
low[u]=t;
for(int i=head[u];i;i=edge[i].nxt){
int v=edge[i].to;
if(!dfn[v]){
q.push(i);
tarjan(v,u);
low[u]=min(low[u],low[v]);
if(low[v]>=dfn[u]){
slt_cnt++;
slt[slt_cnt].clear();
while(){
int num=q.top();
q.pop();
if(numslt[edge[num].st]!=slt_cnt){
numslt[edge[num].st]=slt_cnt;
slt[slt_cnt].push_back(edge[num].st);
}
if(numslt[edge[num].to]!=slt_cnt){
numslt[edge[num].to]=slt_cnt;
slt[slt_cnt].push_back(edge[num].to);
}
if(edge[num].to==v&&edge[num].st==u)break;
}
}
}else if(f!=v){
if(low[u]>dfn[v]){
q.push(i);
low[u]=dfn[v];
}
}
}
return;
}
bool draw(int u){
bool ret=;
for(int i=head[u];i;i=edge[i].nxt){
int v=edge[i].to;
if(!inslt[v])continue;
if(color[v]==-){
color[v]=-color[u];
ret|=draw(v);
}else if(color[v]==color[u]){
return ;
}
}
return ret;
}
void clr(){
cnt=;slt_cnt=;
while(!q.empty())q.pop();
memset(dfn,,sizeof(dfn));
memset(low,,sizeof(low));
memset(numslt,,sizeof(numslt));
memset(head,,sizeof(head));
memset(dis,,sizeof(dis));
memset(ok,,sizeof(ok));
return;
}
int main(){
n=read();
m=read();
while(n||m){
clr();
for(int i=;i<=m;i++){
int u=read();
int v=read();
dis[u][v]=dis[v][u]=;
}
for(int i=;i<=n;i++){
for(int j=i+;j<=n;j++){
if(!dis[i][j]){
add(i,j);
add(j,i);
}
}
}
for(int i=;i<=n;i++){
if(!dfn[i]){
tarjan(i,);
}
}
for(int i=;i<=slt_cnt;i++){
memset(inslt,,sizeof(inslt));
memset(color,-,sizeof(color));
int u;
for(int j=;j<slt[i].size();j++){
u=slt[i][j];
inslt[u]=;
}
color[u]=;
if(draw(u)){
for(int j=;j<slt[i].size();j++){
u=slt[i][j];
ok[u]=;
}
}
}
int ans=;
for(int i=;i<=n;i++)if(!ok[i])ans++;
printf("%d\n",ans);
n=read();m=read();
}
return ;
}
POJ2942:Knights of the Round Table——题解的更多相关文章
- 「题解」:[POJ2942]Knights of the Round Table
问题 E: Knights of the Round Table 时间限制: 1 Sec 内存限制: 256 MB 题面 题目描述 作为一名骑士是一个非常有吸引力的职业:寻找圣杯,拯救遇难的少女,与 ...
- 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 双连通分支 tarjan
题解:http://blog.csdn.net/lyy289065406/article/details/6756821 讲的很详细我就不多说了. 题目连接:http://poj.org/proble ...
- POJ2942 Knights of the Round Table 点双连通分量,逆图,奇圈
题目链接: poj2942 题意: 有n个人,能够开多场圆桌会议 这n个人中,有m对人有仇视的关系,相互仇视的两人坐在相邻的位置 且每场圆桌会议的人数仅仅能为奇书 问有多少人不能參加 解题思路: 首先 ...
- [POJ2942]:Knights of the Round Table(塔尖+二分图染色法)
题目传送门 题目描述 亚瑟王要在圆桌上召开骑士会议,为了不引发骑士之间的冲突,并且能够让会议的议题有令人满意的结果,每次开会前都必须对出席会议的骑士有如下要求: .相互憎恨的两个骑士不能坐在直接相邻的 ...
- POJ2942:Knights of the Round Table
传送门 点双练习. 很简单的一道模板题,建立反图,求出点双,二分图判定奇环. //POJ 2942 //by Cydiater //2016.11.2 #include <iostream> ...
- POJ2942 Knights of the Round Table(点双连通分量 + 二分图染色)
题目大概说要让n个骑士坐成一圈,这一圈的人数要是奇数且大于2,此外有些骑士之间有仇恨不能坐在一起,问有多少个骑士不能入座. 双连通图上任意两点间都有两条不重复点的路径,即一个环.那么,把骑士看做点,相 ...
- poj2942 Knights of the Round Table,无向图点双联通,二分图判定
点击打开链接 无向图点双联通.二分图判定 <span style="font-size:18px;">#include <cstdio> #include ...
- POJ2942 Knights of the Round Table【Tarjan点双联通分量】【二分图染色】【补图】
LINK 题目大意 有一群人,其中有一些人之间有矛盾,现在要求选出一些人形成一个环,这个环要满足如下条件: 1.人数大于1 2.总人数是奇数 3.有矛盾的人不能相邻 问有多少人不能和任何人形成任何的环 ...
随机推荐
- MySQL☞having子句
having子句:是跟group by结合使用,对分组以后的数据再次进行过滤,经常跟聚合函数结合使用 格式: select 列名/聚合函数 from 表名 where 条件 group by ...
- JS获取HTML DOM元素的8种方法
什么是HTML DOM 文档对象模型(Document Object Model),是W3C组织推荐的处理可扩展置标语言的标准编程接口.简单理解就是HTML DOM 是关于如何获取.修改.添加或删除 ...
- 关于html2canvas清晰度
最近有个小项目 需要生成海报让用户去分享~~~vue做的,海报通过html2canvas 生成. 遇到的最大问题是生成图片的清晰度~~网上找了好多方法. 放大倍数!~网上找的~~ var cntEle ...
- 记一次Log4j2日志无法输出的 心酸史
问题描述:部分日志无法输出到日志文件中. 项目中的代码: @Resource private ConfigInfo configInfo; private static final Logger lo ...
- leetcode9_C++判断一个整数是否是回文数
判断一个整数是否是回文数.回文数是指正序(从左向右)和倒序(从右向左)读都是一样的整数. 示例 1: 输入: 输出: true 示例 2: 输入: - 输出: false 解释: 从左向右读, 为 - ...
- Machine Learning笔记整理 ------ (四)线性模型
1. 线性模型 基本形式:给定由d个属性描述的样本 x = (x1; x2; ......; xd),其中,xi是x在第i个属性上的取值,则有: f(x) = w1x1 + w2x2 + ...... ...
- OpenPAI大规模人工智能平台安装部署文档
环境要求: 如果需要图形界面,需要在Ubuntu系统安装,否则centos系统安装时是没有问题的(web端和命令行进行任务提交) 安装过程需要有另外一台控制端机器(注意:区别于集群所在的任何一台服务器 ...
- How Does Batch Normalization Help Optimization?
1. 摘要 BN 是一个广泛应用的用于快速稳定地训练深度神经网络的技术,但是我们对其有效性的真正原因仍然所知甚少. 输入分布的稳定性和 BN 的成功之间关系很小,BN 对训练过程更根本的影响是:它让优 ...
- 在 Ubuntu 下安装 Deepin 的 QQ、微信、百度云和迅雷等软件
在以前的文章 Ubuntu 常用软件推荐(QQ.微信.MATLAB等)及安装过程 中,我们用 Wine QQ 和 Electronic Wechat 来解决 Ubuntu 系统下使用 QQ 和微信的难 ...
- Rightmost Digit(最后一位数字)
Description Given a positive integer N, you should output the most right digit of N^N. Input The ...