POJ 2942 Knights of the Round Table(双连通分量+二分图)
http://poj.org/problem?id=2942
题意: 亚瑟王要在圆桌上召开骑士会议,为了不引发骑士之间的冲突,并且能够让会议的议题有令人满意的结果,每次开会前都必须对出席会议的骑士有如下要求:
1、 相互憎恨的两个骑士不能坐在直接相邻的2个位置;
2、 出席会议的骑士数必须是奇数,这是为了让投票表决议题时都能有结果。
如果出现有某些骑士无法出席所有会议(例如这个骑士憎恨所有的其他骑士),则亚瑟王为了世界和平会强制把他剔除出骑士团。
现在给定准备去开会的骑士数n,再给出m对憎恨对(表示某2个骑士之间使互相憎恨的),问亚瑟王至少要剔除多少个骑士才能顺利召开会议?
注意:1、所给出的憎恨关系一定是双向的,不存在单向憎恨关系。
2、由于是圆桌会议,则每个出席的骑士身边必定刚好有2个骑士。即每个骑士的座位两边都必定各有一个骑士。
3、一个骑士无法开会,就是说至少有3个骑士才可能开会。
分析:本题在刘汝佳训练指南P316有详解.
首先以骑士为节点建立无向图,如果任意两个骑士不互相憎恨,那么就在他们之间连一条无向边.现在问题转换成了有多少骑士不在任意一个奇圈里面?
简单圈上的所有节点必然在同一个(点)双连通分量上.所以我们只需要处理每个(点)双连通分量,看看该双连通分量中是否有奇圈,就可以判断该分量中的点是否在一个奇圈上.我们用odd[i]=1表示i号节点在一个奇圈上.
二分图是没有奇圈的,那么非二分图的双连通分量是不是所有定点都在一个奇圈上呢?首先非二分图的双连通分量肯定存在至少一个奇圈(否则它就是二分的).我们可以证明非二分图的双连通分量的所有顶点都可以被划分到一个奇圈里去.所以这些点都要标记odd[i]=1.(该证明过程请见刘汝佳 训练指南 P317)
综上所述:我们对于每个双连通分量,若它不是二分图,就标记它的所有顶点都在奇圈上(odd[i]=1),最后我们输出的结果就是odd[i]=0的那些点.(注意:割顶属于多个双连通分量,可能被标记多次)
AC代码:
#include<cstdio>
#include<cstring>
#include<vector>
#include<stack>
#include<algorithm>
using namespace std;
const int maxn=1000+10;
int n,m;
int bcc_cnt,dfs_clock;
struct Edge
{
int u,v;
Edge(int u,int v):u(u),v(v){}
};
vector<int> G[maxn],bcc[maxn];
stack<Edge> S;
int pre[maxn],bccno[maxn],iscut[maxn];
int dfs(int u,int fa)
{
int lowu=pre[u]=++dfs_clock;
int child=0;
for(int i=0;i<G[u].size();i++)
{
int v=G[u][i];
if(v==fa) continue;
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;
bcc_cnt++; //从1编号
bcc[bcc_cnt].clear();
while(true)
{
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])
S.push(e), lowu=min(lowu,pre[v]);
}
if(fa<0 && child==1) iscut[u]=false;
return lowu;
}
void find_bcc(int n)
{
memset(pre,0,sizeof(pre));
memset(bccno,0,sizeof(bccno));
memset(iscut,0,sizeof(iscut));
dfs_clock=bcc_cnt=0;
for(int i=0;i<n;i++)
if(!pre[i]) dfs(i,-1);
}
int color[maxn],odd[maxn];
bool bipartite(int u,int b)
{
for(int i=0;i<G[u].size();i++)
{
int v=G[u][i];
if(bccno[v]!=b) continue;
if(color[v]==color[u]) return false;
else if(!color[v])
{
color[v]=3-color[u];
if(!bipartite(v,b)) return false;
}
}
return true;
}
int A[maxn][maxn];
int main()
{
while(scanf("%d%d",&n,&m)==2&&n)
{
memset(A,0,sizeof(A));
for(int i=0;i<n;i++) G[i].clear();
for(int i=0;i<m;i++)
{
int u,v;
scanf("%d%d",&u,&v);
u--;
v--;
A[u][v]=A[v][u]=1;
}
for(int i=0;i<n;i++)
for(int j=i+1;j<n;j++)if(!A[i][j])
{
G[i].push_back(j);
G[j].push_back(i);
}
find_bcc(n);
memset(odd,0,sizeof(odd));
for(int i=1;i<=bcc_cnt;i++)
{
memset(color,0,sizeof(color));
for(int j=0;j<bcc[i].size();j++) bccno[bcc[i][j]]=i;
int u=bcc[i][0];
color[u]=1;
if(!bipartite(u,i))
for(int j=0;j<bcc[i].size();j++) odd[bcc[i][j]]=1;
}
int ans=n;
for(int i=0;i<n;i++)if(odd[i]) ans--;
printf("%d\n",ans);
}
return 0;
}
分享到:
相关推荐
POJ2942-Knights of the Round Table 【Tarjan算法】 解题报告+AC代码 http://hi.csdn.net/!s/F3L8HO ================================== 我的POJ所有解题报告:...
POJ2186-Popular Cows ...【Tarjan+极大强连通分量+缩点】 解题报告+AC代码 http://hi.csdn.net/!s/BGDH68 附:我所有的POJ解题报告链接 . http://blog.csdn.net/lyy289065406/article/details/6642573
北大POJ1426-Find The Multiple【BFS+同余模】 解题报告+AC代码
北大POJ2151-Check the difficulty of problems 解题报告+AC代码
poj 3174 Alignment of the Planets.md
北大POJ3252-Round Numbers 解题报告+AC代码
北大POJ3083-Children of the Candy Corn 解题报告+AC代码
北大POJ2983-Is the Information Reliable【差分约束+优化Bellman】 解题报告+AC代码
业余爱好。所以,算法不一定好,CODING也不一定佳,效率不一定高,只是能通过online judge而已。
北大POJ1027-The Same Game 解题报告+AC代码
北大POJ1584-A Round Peg in a Ground Hole 解题报告+AC代码
北大POJ1163-The Triangle 解题报告+AC代码
北大POJ1207-The 3n + 1 problem 解题报告+AC代码
北大POJ3239-Solution to the n Queens Puzzle 解题报告+AC代码
POJ3177-Redundant Paths 【Tarjan-边双连通分量-缩点】 解题报告+AC代码+测试数据 http://hi.csdn.net/!s/GPAY6Z 附:我所有的POJ解题报告链接 . http://blog.csdn.net/lyy289065406/article/details/6642573
北大POJ1163-The Triangle
北大POJ3267-The Cow Lexicon 解题报告+AC代码
POJ分类POJ分类POJ分类POJ分类POJ分类POJ分类POJ分类POJ分类POJ分类POJ分类POJ分类POJ分类POJ分类POJ分类POJ分类POJ分类POJ分类POJ分类
poj 1611 The Suspects 代码 并查集的应用
poj 2771 Guardian of Decency.md