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 ...
随机推荐
- 慕课网java就业班级
家里电脑教程路径: F:\教程\java-慕课 开发工具路径: D:\java 公司电脑:开发工具路径 J:\java\开发工具 教程路径: G:\学习中\廖雪峰的java教程\1-Java快速入门\ ...
- cassandra的命令
cassandra的命令: connect <hostname>/<port> (<username> '<password>')?; Conne ...
- Image Processing - Pseudo(False) Color Processing
最近在一个项目中有需要用到将图片从GrayScale转为FalseColor,然而百度了一下Halcon 伪彩色等关键字均找不到相关答案,倒是有很多OpenCV和Matlab的...后来在搜索中看到了 ...
- 多列组合为主键(PRIMARY KEY)
在表中,想把其中2列或多列作为组合主键. CREATE TABLE [dbo].[T3] ( ) NOT NULL, ) NOT NULL, ) NULL, ) NULL ) GO ALTER TAB ...
- Swoole 多协议 多端口 的应用
目录 概述 网络通信协议设计 多端口监听的使用 小结 概述 这是关于 Swoole 学习的第五篇文章:Swoole 多协议 多端口 的应用. 第四篇:Swoole HTTP 的应用 第三篇:Swool ...
- Git 分支管理 解决冲突
人生不如意之事十之八九,合并分支往往也不是一帆风顺的. 准备新的feature1分支,继续我们的新分支开发: $ git checkout -b feature1 -- 在feature1分支上修改r ...
- 3DMAX 多维材质及对应的UVW展开,UVW贴图
多维材质说明 多维材质就是一个模型多个材质,(混合材质是多个材质混一起,跟这个貌似没关,比如地表草地,泥土等的混合操作) 作用: 比如一个模型就是需要两种材质,刀的金属刀身,木质刀柄,墙的一面是木板, ...
- OpenGL学习笔记——求值器和NURBS
http://codercdy.com/openglxue-xi-bi-ji-qiu-zhi-qi-he-nurbs/ 在最底层,图形硬件所绘制的是点.直线和多边形(通常是三角形和四边形).平滑的曲线 ...
- 洛谷P2016 战略游戏
P2016 战略游戏 题目描述 Bob喜欢玩电脑游戏,特别是战略游戏.但是他经常无法找到快速玩过游戏的办法.现在他有个问题. 他要建立一个古城堡,城堡中的路形成一棵树.他要在这棵树的结点上放置最少数目 ...
- Python学习笔记(数据处理)
处理文件中数据 (统计分数) 看一下我们的文档里的数据: #-- scores.txt 刘备 23 35 44 47 51 关羽 60 77 68 张飞 97 99 89 91 诸葛亮 100 1.先 ...