码迷,mamicode.com
首页 > 其他好文 > 详细

poj 2942 Knights of the Round Table

时间:2019-07-10 11:07:11      阅读:84      评论:0      收藏:0      [点我收藏+]

标签:scanf   space   pac   can   tar   eof   ref   main   unsigned   

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

引理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

标签:scanf   space   pac   can   tar   eof   ref   main   unsigned   

原文地址:https://www.cnblogs.com/Hikigaya/p/11161974.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!