题目真心分析不出来。看了白书才明白,不过有点绕脑。

容易想到,把题目给的不相邻的关系,利用矩阵,反过来建图。既然是全部可行的关系,那么就应该能画出含奇数个点的环。求环即是求双连通分量:找出所有的双连通分量,只要分量中的点数是奇数,则排除“must be expelled”的可能性。

判环上的点数用二分图,这个我都想了半天= =,如果是奇数个点,明摆着多出来的一个点放到哪个集合都会与集合内的点连边(这个找三个点自己画画试试就明白了)。0、1染色,本人喜欢用bfs,递归什么的其实都可以。

我自己用缩点做的,果断wa到吐。举个例子:五个点,{1,2,3}{3,4,5},这样3就是一个割顶了,缩点的话是在遍历完邻接表之后,再判断low[u]==dfn[u],如此5个点就缩成了一个点,即一个分量,虽然这个分量包含奇数个点,输出同样是0,但与我们的思路是不一样的。实际情况是分成两个分量,每个分量有三个点,割顶3同时出现在两个分量中。然后想着改进,当把割顶弹出栈后,再弹入,搞啊搞,还是算了,学着白书上用边搞。

 #include<stdio.h>
#include<string.h>
#include<vector>
#include<stack>
#include<algorithm>
using namespace std; const int MAXN=; struct EDGE{
int u,v;
EDGE(){}
EDGE(int _u,int _v):u(_u),v(_v){}
}; struct Edge{
int v,next;
Edge(){}
Edge(int _v,int _next):v(_v),next(_next){}
}edge[MAXN*MAXN]; int mp[MAXN][MAXN],tol,head[MAXN];
int low[MAXN],dfn[MAXN],bccno[MAXN],iscut[MAXN],TT,bcc_cnt;
int que[MAXN],color[MAXN];
int sign[MAXN]; vector<int >bcc[MAXN];
stack<EDGE >stk; void init()
{
tol=;
memset(head,-,sizeof(head));
} void add(int u,int v)
{
edge[tol]=Edge(v,head[u]);
head[u]=tol++;
} void dfs(int u,int fa)
{
low[u]=dfn[u]=++TT;
int son=;
for(int i=head[u];i!=-;i=edge[i].next)
{
int v=edge[i].v;
EDGE e=EDGE(u,v);
if(!dfn[v]){
stk.push(e);
son++;
dfs(v,u);
low[u]=min(low[v],low[u]);
if(low[v]>=low[u]){
iscut[u]=;
bcc_cnt++;
bcc[bcc_cnt].clear();
while()
{
EDGE x=stk.top();
stk.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(dfn[v]<dfn[u]&&v!=fa){
stk.push(e);
low[u]=min(low[u],dfn[v]);
}
}
if(fa<&&son==)
iscut[u]=;
} void find_bcc(int n)
{
memset(low,,sizeof(low));
memset(dfn,,sizeof(dfn));
memset(bccno,,sizeof(bccno));
memset(iscut,,sizeof(iscut)); TT=bcc_cnt=; for(int i=;i<=n;i++)
if(!dfn[i])
dfs(i,-);
} bool bfs(int x,int fa)
{
int l,r;
l=r=;
que[r++]=x;
while(l<r)
{
int u=que[l++];
for(int i=head[u];i!=-;i=edge[i].next)
{
int v=edge[i].v;
if(bccno[v]!=fa)
continue ;
if(color[v]==-){
color[v]=color[u]^;
que[r++]=v;
}else if(color[v]==color[u])
return false;
}
}
return true;
} void Bjudge()
{
memset(sign,,sizeof(sign));
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(!bfs(u,i)){
for(int j=;j<bcc[i].size();j++)
sign[bcc[i][j]]=;
}
}
} int main()
{
int n,m;
int a,b;
while(~scanf("%d%d",&n,&m)!=EOF)
{
if(!n&&!m)
break;
memset(mp,,sizeof(mp));
for(int i=;i<m;i++)
{
scanf("%d%d",&a,&b);
mp[a][b]=mp[b][a]=;
} init();
for(int i=;i<=n;i++)
{
for(int j=i+;j<=n;j++)
{
if(!mp[i][j]){
add(i,j);
add(j,i);
}
}
} find_bcc(n); Bjudge(); int ans=;
for(int i=;i<=n;i++)
if(!sign[i])
ans++;
printf("%d\n",ans);
}
return ;
}
/*
5 4
1 4
1 5
2 4
2 5 6 8
1 4 1 5 1 6
2 4 2 5 2 6
3 4 3 5
*/

最近做了几道connectivity的题目,总结一下。

关于割顶、桥、双连通、边双连通,以及强连通处理方式有其相似性,关键都与时间戳有关。

其中,割顶->双连通 是low[v]>=dfn[u],桥->边双连通 是low[v]>dfn[u],只是一个等号的差别,其他处理基本相同;而强连通总是伴随着缩点 low[u]==dfn[u](这个一般是做边标记edge[].vis,这样即使是无向图也可以以edge[i^1].vis标记掉,而不影响重边的情况)。事实上,如果不考虑具体的桥,对边-双连通分量的划分就是在做无向图上的缩点操作。

这三个判定条件的位置也有不同。缩点是在遍历完u的邻接表之后,用每个low[v]的值更新low[u],并且u本身不会连到祖先去(这一点很重要),则是一个环,可以缩掉;在无向图中,判断双连通分量,也就是割顶(边-双连通分量&桥 一样),是每遍历一个孩子v,就要判断:low[v]>=dfn[u],只要点u的孩子所能到达的最大值不超过u,那么u就是割顶(删除u后,该子树独立),当然,u的每一个孩子v都可以是被 割顶u 分离,注意u本身是可以与它的祖先连接的!!

uvalive 3523 Knights of the Round Table 圆桌骑士(强连通+二分图)的更多相关文章

  1. UVALive 3523 Knights of the Round Table 圆桌骑士 (无向图点双连通分量)

    由于互相憎恨的骑士不能相邻,把可以相邻的骑士连上无向边,会议要求是奇数,问题就是求不在任意一个简单奇圈上的结点个数. 如果不是二分图,一定存在一个奇圈,同一个双连通分量中其它点一定可以加入奇圈.很明显 ...

  2. UVALive - 3523 - Knights of the Round Table

    Problem  UVALive - 3523 - Knights of the Round Table Time Limit: 4500 mSec Problem Description Input ...

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

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

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

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

  5. UVALive 3523 : Knights of the Round Table (二分图+BCC)

    题目链接 题意及题解参见lrj训练指南 #include<bits/stdc++.h> using namespace std; ; int n,m; int dfn[maxn],low[ ...

  6. KNIGHTS - Knights of the Round Table 圆桌骑士 点双 + 二分图判定

    ---题面--- 题解: 考场上只想到了找点双,,,,然后不知道怎么处理奇环的问题. 我们考虑对图取补集,这样两点之间连边就代表它们可以相邻, 那么一个点合法当且仅当有至少一个大小至少为3的奇环经过了 ...

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

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

  8. uva 3523 Knights of the Round Table

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

  9. UVALive-3523 Knights of the Round Table (双连通分量+二分图匹配)

    题目大意:有n个骑士要在圆桌上开会,但是相互憎恶的两个骑士不能相邻,现在已知骑士们之间的憎恶关系,问有几个骑士一定不能参加会议.参会骑士至少有3个且有奇数个. 题目分析:在可以相邻的骑士之间连一条无向 ...

随机推荐

  1. 3036: 绿豆蛙的归宿 - BZOJ

    Description 随着新版百度空间的下线,Blog宠物绿豆蛙完成了它的使命,去寻找它新的归宿. 给出一个有向无环的连通图,起点为1终点为N,每条边都有一个长度.绿豆蛙从起点出发,走向终点.到达每 ...

  2. ubuntu下opencv 3.0和python2.7安装测试

    1.安装opencv所需的库(编译器.必须库.可选库) sudo apt-get install build-essential sudo apt-get install cmake git libg ...

  3. VisionTimer BUG && Start

    void Start() { vp_Timer.In(0.0f, delegate() { Debug.Log("Start"); }, 10, 1.0f); } Version ...

  4. java.util.ResourceBundle

    转载自: http://lavasoft.blog.51cto.com/62575/184605 这个类提供软件国际化的捷径.通过此类,可以使您所编写的程序可以:          轻松地本地化或翻译 ...

  5. poj 3625 Building Roads(最小生成树,二维坐标,基础)

    题目 //最小生成树,只是变成二维的了 #define _CRT_SECURE_NO_WARNINGS #include<stdlib.h> #include<stdio.h> ...

  6. POJ 1663

    #include<iostream>//cheng da cai zi using namespace std; int main() { int time; cin>>tim ...

  7. hdu 4430 Yukari's Birthday

    思路: 分析知道1<=r<40:所以可以枚举r,之后再二分k. 代码如下: #include<iostream> #include<stdio.h> #includ ...

  8. intellij idea 12、13 win8 下 中文输入覆盖的问题(搜狗输入法或者其他输入法)

    最近升级到idea12,发现中文输入存在问题,输入中文的时候会出现空格,并且覆盖后面的字符,这个问题让我很郁闷. 假设idea的安装位置为:D:\Program Files\JetBrains\Int ...

  9. hdu1022 Train Problem I

    http://acm.hdu.edu.cn/showproblem.php?pid=1022 #include<iostream> #include<stdio.h> #inc ...

  10. java retention注解

    Retention注解 Retention(保留)注解说明,这种类型的注解会被保留到那个阶段. 有三个值:1.RetentionPolicy.SOURCE —— 这种类型的Annotations只在源 ...