poj 2942 Knights of the Round Table

Posted hikigaya

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了poj 2942 Knights of the Round Table相关的知识,希望对你有一定的参考价值。

先建补图,一组士可以一组的条件是他们成奇环

引理1:若2个骐士属于2个不同的点双,则他们不可能一起出席,易证

引理2:若一v-dcc中有奇环,则每个点都被至少一个奇环包围,易证

于是求所有的v-dcc再分别染色判奇环就行了

我括号打错了一个调了nmb一下午我透

#include<bits/stdc++.h>
using namespace std;
const int N=1007;
const int M=1000007;
int n,m,tot=1,head[N],nxt[M],ver[M],root,cnt,dfn[N],low[N],s[N],top,num,c[N],v[N],t[N];
void add(int x,int y)
    ver[++tot]=y;
    nxt[tot]=head[x];
    head[x]=tot;

vector <int> dcc[N];
bool Map[N][N],flag;
void tarjan(int x)
    dfn[x]=low[x]=++num;
    s[++top]=x;
    if(x==root&&head[x]==0)
        dcc[++cnt].push_back(x);
        return;
    
    for(int i=head[x];i;i=nxt[i])
        int y=ver[i];
        if(!dfn[y])
            tarjan(y);
            low[x]=min(low[x],low[y]);
            if(low[y]>=dfn[x])
                cnt++;
                int z;
                do
                    z=s[top--];
                    dcc[cnt].push_back(z);
                while(z!=y);
                dcc[cnt].push_back(x);
                
        
        else low[x]=min(low[x],dfn[y]);
    

void dfs(int x,int col)
    c[x]=col;
    for(int i=head[x];i;i=nxt[i])
        int y=ver[i];
        if(v[y]!=v[x])continue;
        if(c[y]&&c[y]==col)
            flag=1;
            return;
        
        if(!c[y]) 
            dfs(y,3-col);
        
    

int main()
    while(cin>>n>>m&&n)
        cnt=num=top=0;
        tot=1;
        for(int i=1;i<=n;i++)
            dfn[i]=head[i]=0;
        for(int i=1;i<=m;i++)
            ver[i]=nxt[i]=0;
        memset(Map,0,sizeof(Map));
        for(int i=1;i<=n;i++)
            dcc[i].clear();
        memset(t,0,sizeof(t));
        memset(v,0,sizeof(v));
        for(int i=1;i<=n;i++)
            Map[i][i]=1;
        for(int i=1;i<=m;i++)
            int x,y;
            scanf("%d%d",&x,&y);
            if(x==y)continue;
            Map[x][y]=Map[y][x]=1;
        
        for(int i=1;i<n;i++)
            for(int j=i+1;j<=n;j++)
                if(!Map[i][j])
                    add(i,j);
                    add(j,i);
                
        for(int i=1;i<=n;i++)
            if(!dfn[i])
                root=i;
                tarjan(i);
            
        
        int ans=0;
        for(int i=1;i<=cnt;i++)
            for(unsigned int j=0;j<dcc[i].size();j++)
                int y=dcc[i][j];
                v[y]=i;
                c[y]=0;
            
            flag=0;
            dfs(dcc[i][0],1);
            if(flag)
                for(unsigned int j=0;j<dcc[i].size();j++)
                    t[dcc[i][j]]=1;
                
            
        
        for(int i=1;i<=n;i++)
            if(!t[i])ans++;
        printf("%d\\n",ans);
    
    return 0;

 

以上是关于poj 2942 Knights of the Round Table的主要内容,如果未能解决你的问题,请参考以下文章

poj2942 Knights of the Round Table

poj2942:Knights of the Round Table——题解

poj2942 Knights of the Round Table

POJ 2942Knights of the Round Table(二分图判定+双连通分量)

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

poj 2942 Knights of the Round Table