poj2942 Knights of the Round Table

Posted tmzengbi

tags:

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

好久之前就注册了一直没写 今天开始把刷的题都放在上面

这个题就是建个补图找双连通分量然后染色判断是不是二分图(奇圈一定不是二分图)

re了好多次 debug2小时 最后发现栈数组开小了。。。

#include<iostream>
#include<cstring>
#include<cstdio>
#include<algorithm>
#include<vector>
using namespace std;
const int maxn=1010;
struct Edge
{
    int u,v;
}s[1000010];
int dfn[maxn],low[maxn],cnt=0,cnt_bcc=0,a[maxn][maxn],N,M,Index=0,belong[maxn],col[maxn];
bool iscut[maxn],mk[maxn];
vector<int> edges[maxn];
vector<int> bcc[maxn];
void addedge(int u,int v)
{
    edges[u].push_back(v);
    edges[v].push_back(u);
}
bool isbipartite(int u,int C)
{
    for(int i=0;i<edges[u].size();i++)
    {
        int v=edges[u][i];
        if(belong[v]!=C) continue;
        if(col[u]==col[v]) return false;
        if(!col[v])
        {    
            col[v]=3-col[u];
            if(!isbipartite(v,C)) return false;
//            return isbipartite(v,C);
        }
    }
    return true;
}
void init()
{
    for(int i=1;i<=N;i++)
        edges[i].clear();
    memset(a,0,sizeof a);
    memset(dfn,0,sizeof dfn);
    memset(belong,0,sizeof belong);
    memset(iscut,false,sizeof iscut);
    memset(mk,false,sizeof mk);
    cnt=0;cnt_bcc=0;
}
void tarjan(int u,int fa)
{
    int child=0;
    dfn[u]=low[u]=++cnt;
    for(int i=0;i<edges[u].size();i++)
    {
        int v=edges[u][i];
        if(!dfn[v])
        {
            child++;
            s[++Index]=(Edge){u,v};
            tarjan(v,u);
            low[u]=min(low[u],low[v]);
            if(low[v]>=dfn[u])
            {
                iscut[u]=true;cnt_bcc++;
                bcc[cnt_bcc].clear();
                for(Edge e;;)
                {
                    e=s[Index--];
                    if(belong[e.u]!=cnt_bcc){belong[e.u]=cnt_bcc;bcc[cnt_bcc].push_back(e.u);}
                    if(belong[e.v]!=cnt_bcc){belong[e.v]=cnt_bcc;bcc[cnt_bcc].push_back(e.v);}
                    if(e.u==u&&e.v==v) break;
                }
            }
        }
        else if(dfn[v]<dfn[u]&&fa!=v)
        {
            s[++Index]=(Edge){u,v};
            low[u]=min(low[u],dfn[v]);
        }
        if(child==1&&fa==0) iscut[u]=false;
    }
}
int main()
{
    while(true)
    {

        scanf("%d%d",&N,&M);
        if(N==0&&M==0) break;
        init();
        for(int i=1;i<=M;i++)
        {
            int u,v;
            scanf("%d%d",&u,&v);
            a[u][v]=1;a[v][u]=1;
        }
        for(int i=1;i<=N;i++)
            for(int j=1+i;j<=N;j++)
                if(!a[i][j]) addedge(i,j);
        for(int i=1;i<=N;i++)
            if(!dfn[i]) tarjan(i,0);
        for(int i=1;i<=cnt_bcc;i++)
        {
            memset(col,0,sizeof col);
            for(int j=0;j<bcc[i].size();j++)
                belong[bcc[i][j]]=i;
            col[bcc[i][0]]=1;
            if(!isbipartite(bcc[i][0],i))
                for(int j=0;j<bcc[i].size();j++)
                    mk[bcc[i][j]]=1;
        }
        int ans=N;
        for(int i=1;i<=N;i++)
            if(mk[i]) ans--;
        printf("%d
",ans);
    }
    return 0;
}

看的蓝书的思路 debug时把代码刘汝佳化了

以上是关于poj2942 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