UVALive 3523 Knights of the Round Table 圆桌骑士 (无向图点双连通分量)
由于互相憎恨的骑士不能相邻,把可以相邻的骑士连上无向边,会议要求是奇数,问题就是求不在任意一个简单奇圈上的结点个数。
如果不是二分图,一定存在一个奇圈,同一个双连通分量中其它点一定可以加入奇圈。很明显,其它点和已知的奇圈相连总是有两条点数一奇一偶的路径,
因此一定可以找到一条回路使得新的这个点加入一个奇圈。
#include<bits/stdc++.h>
using namespace std;
#define bug(x) cout<<#x<<'='<<x<<endl;
const int maxv = +;
const int maxe = maxv*maxv;//开小 int dfn[maxv],low[maxv],bccno[maxv],dfs_clock,bcc_cnt;
bool iscut[maxv];
vector<int> bcc[maxv];
int head[maxv],fro[maxe],to[maxe],nxt[maxe],ecnt; int edges[maxe],top; void addEdge(int u,int v)
{
fro[ecnt] = u;
to[ecnt] = v;
nxt[ecnt] = head[u];
head[u] = ecnt++;
} void tarjan(int u,int fa)
{
dfn[u] = low[u] = ++dfs_clock;
for(int i = head[u]; ~i; i = nxt[i]){
int v = to[i]; if(!dfn[v]){
edges[++top] = i;
tarjan(v,i);
low[u] = min(low[v],low[u]);
if(low[u] >= dfn[u]){
iscut[u] = true;
bcc_cnt++; bcc[bcc_cnt].clear(); //bcc从1开始
int U,V;
do{
int e = edges[top--];
U = fro[e], V = to[e];
if(bccno[U] != bcc_cnt) { bcc[bcc_cnt].push_back(U); bccno[U]=bcc_cnt; }
if(bccno[V] != bcc_cnt) { bcc[bcc_cnt].push_back(V); bccno[V]=bcc_cnt; }
}while(U!=u||V!=v);
}
}else if((i^) != fa && dfn[v] < dfn[u] ){ low[u] = min(low[u],dfn[v]); edges[++top] = i; }// == 比 ^优先级高!第二个条件少了会WA是什么原因
}
} void find_bcc(int n)
{
top = ;
memset(dfn ,,sizeof(dfn));
memset(iscut, ,sizeof(iscut));
memset(bccno, ,sizeof(bccno));
dfs_clock = bcc_cnt = ;
for(int i = ; i < n; i++) {
if(!dfn[i]) {
tarjan(i,-);
iscut[i] = ~nxt[head[i]];// !(nxt[head[i]] == -1);//树根特判,如果只有一个子结点false
}
}
} int color[maxv];
bool bipartite(int u, int b)
{
for(int i = head[u]; ~i; i = nxt[i]){
int v = to[i]; if(bccno[v] != b) continue;
if(color[v] == color[u]) return false;
if(!color[v]){
color[v] = - color[u];
if(!bipartite(v,b)) return false;
}
}
return true;
} bool hate[maxv][maxv];
bool inOdd[maxv]; int main()
{
//freopen("in.txt","r",stdin);
int n,m;
while(~scanf("%d%d",&n,&m)&&(n||m)){
memset(hate,,sizeof(hate));
while(m--){
int u,v; scanf("%d%d",&u,&v); u--,v--;
hate[u][v] = hate[v][u] = true;
}
memset(head,-,sizeof(head)); ecnt = ;
for(int i = ; i < n; i++)
for(int j = i+; j < n; j++) if(!hate[i][j]){
addEdge(i,j); addEdge(j,i);
}
find_bcc(n);
// bug(bcc_cnt);
memset(inOdd,,sizeof(inOdd));
for(int i = ; i <= bcc_cnt; i++){
memset(color,,sizeof(color));
for(int j = ; j < bcc[i].size(); j++) bccno[bcc[i][j]] = i; //割点,属于多个连通分量,因此特殊处理
int u = bcc[i][];
color[u] = ;
if(!bipartite(u,i)){
for(int j = ; j < bcc[i].size(); j++) inOdd[bcc[i][j]] = true;
}
}
int ans = n;
for(int i= ; i < n; i++) if(inOdd[i]) ans--;
printf("%d\n",ans);
}
return ;
}
UVALive 3523 Knights of the Round Table 圆桌骑士 (无向图点双连通分量)的更多相关文章
- uvalive 3523 Knights of the Round Table 圆桌骑士(强连通+二分图)
题目真心分析不出来.看了白书才明白,不过有点绕脑. 容易想到,把题目给的不相邻的关系,利用矩阵,反过来建图.既然是全部可行的关系,那么就应该能画出含奇数个点的环.求环即是求双连通分量:找出所有的双连通 ...
- UVALive - 3523 - Knights of the Round Table
Problem UVALive - 3523 - Knights of the Round Table Time Limit: 4500 mSec Problem Description Input ...
- POJ2942 UVA1364 Knights of the Round Table 圆桌骑士
POJ2942 洛谷UVA1364(博主没有翻墙uva实在是太慢了) 以骑士为结点建立无向图,两个骑士间存在边表示两个骑士可以相邻(用邻接矩阵存图,初始化全为1,读入一对憎恨关系就删去一条边即可),则 ...
- poj 2942 Knights of the Round Table 圆桌骑士(双连通分量模板题)
Knights of the Round Table Time Limit: 7000MS Memory Limit: 65536K Total Submissions: 9169 Accep ...
- UVALive 3523 : Knights of the Round Table (二分图+BCC)
题目链接 题意及题解参见lrj训练指南 #include<bits/stdc++.h> using namespace std; ; int n,m; int dfn[maxn],low[ ...
- KNIGHTS - Knights of the Round Table 圆桌骑士 点双 + 二分图判定
---题面--- 题解: 考场上只想到了找点双,,,,然后不知道怎么处理奇环的问题. 我们考虑对图取补集,这样两点之间连边就代表它们可以相邻, 那么一个点合法当且仅当有至少一个大小至少为3的奇环经过了 ...
- uva 3523 Knights of the Round Table
题意:给你n,m n为有多少人,m为有多少组关系,每组关系代表两人相互憎恨,问有多少个骑士不能参加任何一个会议. 白书算法指南 对于每个双联通分量,若不是二分图,就把里面的节点标记 #include ...
- POJ 2942 Knights of the Round Table 补图+tarjan求点双联通分量+二分图染色+debug
题面还好,就不描述了 重点说题解: 由于仇恨关系不好处理,所以可以搞补图存不仇恨关系, 如果一个桌子上面的人能坐到一起,显然他们满足能构成一个环 所以跑点双联通分量 求点双联通分量我用的是向栈中pus ...
- [LA3523/uva10195]圆桌骑士 tarjan点双连通分量+奇环定理+二分图判定
1.一个环上的各点必定在同一个点双连通分量内: 2.如果一个点双连通分量是二分图,就不可能有奇环: 最基本的二分图中的一个环: #include<cstdio> #include<c ...
随机推荐
- shader之顶点着色器
Vertex Shader 是渲染管道中一个可编程的模块,用于处理独立的顶点.Vertex Shader接收Vertex Attribute Data,由定点数组对象通过渲染指令来生成. Vertex ...
- LeetCode: 492 Construct the Rectangle(easy)
题目: or a web developer, it is very important to know how to design a web page's size. So, given a sp ...
- 特性attribute,声明和使用attribute,应用attribute,AOP面向切面,多种方式实现AOP
1 特性attribute,和注释有什么区别2 声明和使用attribute3 应用attribute4 AOP面向切面5 多种方式实现AOP ---------------------------- ...
- MVC实用笔记
---------------------------- 渲染一个Action:@{Html.RenderAction("Rulelist", "AjaxReuqestD ...
- Swoole HTTP 的应用
目录 概述 代码 小结 扩展 概述 这是关于 Swoole 学习的第四篇文章:Swoole HTTP 的应用. 第三篇:Swoole WebSocket 的应用 第二篇:Swoole Task 的应用 ...
- MYSQL中coalesce函数的用法
coalesce():返回参数中的第一个非空表达式(从左向右依次类推): 例如: select coalesce(null,4,5); // 返回4 select coalesce(null,null ...
- atcode062D(预处理&优先队列)
题目链接:http://abc062.contest.atcoder.jp/tasks/arc074_b 题意:从3*n个元素中删除n个元素,使得剩余元素中前n个元素的和减后n个元素的和最大: 思路: ...
- c语言中的switch case语句
switch--case语句中,switch后面跟一个变量,这个变量不可以是字符数组,字符指针,字符串数组,浮点型(实型).它可以是整型,字符型(在本质上也是整型).所以这导致case后面的常量表达式 ...
- ios Realm的使用 本地数据存储
引入需要的文件 pod 'RealmSwift' pod 'Realm' 然后在命令行使用 (首先应该cd到项目的根目录)输入 pod install 等待下载就行了(这个下载有点费劲,其他的插件包下 ...
- 题解 BZOJ 1912 && luogu P3629 [APIO2010]巡逻 (树的直径)
本来抄了篇题解,后来觉得题解都太不友好(我太菜了),一气之下自己打...一打打到第二天QAQ 首先什么边也不加时,总路程就是2*(n-1) 考虑k=1的时候,答案显然是2*(n-1)-直径+1=2*n ...