Knights of the Round Table--POJ 2942
2010-08-10 21:42
344 查看
1、题目类型:图论、点双强连通分量、Tarjan算法。
2、解题思路:题意,N个骑士中某些骑士之间会有仇恨。骑士们开会时围坐在一个圆桌旁。一次会议能够举行,当且仅当没有相邻的两个骑士相互仇恨,且开会人数为大于2的奇数。若某个骑士任何会议都不能参加,那么就必须将它踢出。给出骑士之间的仇恨关系,问需要踢出多少个骑士。步骤,(1)建立输入图的补图;(2)类似Trajan算法求解并记录点双强连通分量;(3)寻找最大强连通分量奇圈。
3、注意事项:两条重要定理:若某块不可染色为二分图,则该块存在奇圈;若某块存在奇圈,那么该块中的所有点都存在与奇圈中;表示图的节点间关系时,用vector表示,用邻接表表示TLE。
4、实现方法:
2、解题思路:题意,N个骑士中某些骑士之间会有仇恨。骑士们开会时围坐在一个圆桌旁。一次会议能够举行,当且仅当没有相邻的两个骑士相互仇恨,且开会人数为大于2的奇数。若某个骑士任何会议都不能参加,那么就必须将它踢出。给出骑士之间的仇恨关系,问需要踢出多少个骑士。步骤,(1)建立输入图的补图;(2)类似Trajan算法求解并记录点双强连通分量;(3)寻找最大强连通分量奇圈。
3、注意事项:两条重要定理:若某块不可染色为二分图,则该块存在奇圈;若某块存在奇圈,那么该块中的所有点都存在与奇圈中;表示图的节点间关系时,用vector表示,用邻接表表示TLE。
4、实现方法:
#define MAXN 1010 #include<iostream> #include<vector> using namespace std; int color[MAXN],use[MAXN],mat[MAXN][MAXN]; vector<int> map[MAXN]; int n,m,cnt,ans; int b[MAXN]; bool IsOk(int v,int val) { int i,j; color[v]=val; for(j=0;j<map[v].size();j++) { i=map[v][j]; if(i==v) continue; if(b[i]) { if(color[v]==color[i]) return true; if(color[i]==-1) IsOk(i,val^1); } } return false; } void Dummy(int t,int* a) { int i,j; memset(b,0,sizeof(b)); for(j=0;j<t;j++) b[a[j]]=1; for(i=0;i<t;i++) { memset(color,-1,sizeof(color)); if(IsOk(a[i],1)) break; } if(i<t) { for(j=0;j<t;j++) { if(!use[a[j]]) { ans++; use[a[j]]=1; } } } } void Search(int n,vector<int> mat[MAXN],int* dfn,int* low,int now,int& cnt,int* st,int& sp) { int i,j,m,a[MAXN]; dfn[st[sp++]=now]=low[now]=++cnt; for (j=0;j<mat[now].size();j++) { i=mat[now][j]; if (!dfn[i]) { Search(n,mat,dfn,low,i,cnt,st,sp); if (low[i]<low[now]) low[now]=low[i]; if (low[i]>=dfn[now]) { for (st[sp]=-1,a[0]=now,m=1;st[sp]!=i;a[m++]=st[--sp]); Dummy(m,a); } } else if (dfn[i]<low[now]) low[now]=dfn[i]; } } //求点双连通分量即块 void Block(int n,vector<int> mat[MAXN]) { int i,cnt,dfn[MAXN],low[MAXN],st[MAXN],sp=0; for (i=0;i<n;dfn[i++]=0); for (cnt=i=0;i<n;i++) if (!dfn[i]) Search(n,mat,dfn,low,i,cnt,st,sp); } void Init() { int i,j,a,b; memset(mat,0,sizeof(mat)); for(i=0;i<m;i++) { scanf("%d%d",&a,&b); a--; b--; mat[a][b]=mat[b][a]=1; } //转换为补图 for(i=0;i<n;i++) map[i].clear(); for(i=0;i<n;i++) { for(j=0;j<n;j++) { if(!mat[i][j]) { map[i].push_back(j); map[j].push_back(i); } } } memset(use,0,sizeof(use)); cnt=0,ans=0; } int main() { while(scanf("%d%d",&n,&m)) { if(n==0&&m==0) break; Init(); Block(n,map); cout<<n-ans<<endl; } return 0; }
相关文章推荐
- POJ 2942 Knights of the Round Table ★(点双连通分量+二分图判定)
- POJ2942:Knights of the Round Table
- poj2942 Knights of the Round Table
- poj 2942 Knights of the Round Table(双连通分量+tarjan+二分图判定)
- POJ-2942 Knights of the Round Table
- (点双联通分量模板)POJ 2942 Knights of the Round Table 圆桌骑士
- Knights of the Round Table POJ - 2942
- 【连通图|双连通+二分图判定】POJ-2942 Knights of the Round Table
- POJ 2942 Knights of the Round Table ★(点双连通分量+二分图判定)
- 【POJ】2942 Knights of the Round Table(双连通分量)
- POJ2942 Knights of the Round Table(双联通分量+奇圈判断)
- POJ-2942-Knights of the Round Table
- POJ2942 Knights of the Round Table(点双连通分量 + 二分图染色)
- POJ 2942 Knights of the Round Table 黑白着色+点双连通分量
- poj 2942 Knights of the Round Table 【双连通缩点+判奇圈】【经典】
- POJ2942-Knights of the Round Table
- poj 2942 Knights of the Round Table Tarjan求点双联通分量+黑白染色二分图判断
- POJ_2942_Knights of the Round Table(点的双连通分量+二分图判定)
- POJ 2942--Knights of the Round Table(双连通分量)
- poj 2942 Knights of the Round Table