【综合图论】PKU-2942-Knights of the Round Table

原创 2012年03月29日 19:58:03

综合性很强的一道图论题,用到了补图,双连通分量,二分图等几个知识点,这里有某位大牛的神解题报告点击打开链接

题目

#include<iostream>
#include<cstdio>
#include<cstring>
#include<vector>
#include<stack>
using namespace std;
#define N 1005
vector<int> vec[N],lin[N];
stack<int> sta;
int n,step,cnt,ans,low[N],dfn[N],ins[N],col[N];
bool p[N][N];
void tarjan(int now,int pre)
{
    low[now]=dfn[now]=step++;
    sta.push(now);
    ins[now]=1;
    int len=vec[now].size();
    for(int i=0;i<len;i++)
    {
        int u=vec[now][i];
        if(u==pre)continue;
        if(dfn[u]==-1)
        {
            tarjan(u,now);
            low[now]=min(low[now],low[u]);
            if(low[u]>=dfn[now])
            {
                while(1)
                {
                    int x=sta.top();
                    sta.pop();
                    ins[x]=0;
                    lin[cnt].push_back(x);
                    if(u==x)break;
                }
                lin[cnt++].push_back(now);
            }
        }
        else
        {
            if(ins[u])low[now]=min(low[now],dfn[u]);
        }
    }
}
void dfs(int id,int u,int c)
{
    col[u]=c;
    int len=lin[id].size();
    for(int i=0;i<len;i++)
    {
        int x=lin[id][i];
        if(u==x||col[x]!=-1)continue;
        if(!p[u][x])dfs(id,x,c^1);            //找相邻的点染与当前点不同的色
    }
}
void slove()
{
    cnt=step=0;
    while(!sta.empty())sta.pop();
    memset(ins,0,sizeof(ins));
    memset(dfn,-1,sizeof(dfn));
    for(int i=0;i<n;i++)            //tarjan算法求连通分支
    {
        if(dfn[i]!=-1)continue;
        tarjan(i,-1);
    }
    bool ok[N];
    memset(ok,false,sizeof(ok));
    for(int i=0;i<cnt;i++)
    {
        memset(col,-1,sizeof(col));
        dfs(i,lin[i][0],0);            //染色
        int len=lin[i].size();
        bool flag=false;
        for(int j=0;j<len;j++)
        {
            for(int k=0;k<len;k++)
            {
                int x=lin[i][j];
                int y=lin[i][k];
                if(x!=y&&!p[x][y]&&col[x]==col[y])            //判断是否是二分图,如果x和y相邻并且他们同色就说明这个连通分支不是二分图
                {
                    flag=true;
                    break;
                }
            }
            if(flag)break;
        }
        if(flag)
        {
            for(int j=0;j<len;j++)ok[lin[i][j]]=true;            //不是二分图既是奇圈,里面的点都符合要求
        }
    }
    ans=0;
    for(int i=0;i<n;i++)
    {
        if(!ok[i])ans++;            //找出不在奇圈的点数
    }
}
int main()
{
    //freopen("a.txt","r",stdin);
    int m;
    while(scanf("%d%d",&n,&m)&&n+m)
    {
        memset(p,false,sizeof(p));
        for(int i=0;i<m;i++)
        {
            int x,y;
            scanf("%d%d",&x,&y);
            x--,y--;
            p[x][y]=p[y][x]=true;
        }
        for(int i=0;i<n;i++)
        {
            vec[i].clear();
            lin[i].clear();
        }
        for(int i=0;i<n;i++)            //取补图
        {
            for(int j=0;j<n;j++)
            {
                if(p[i][j]&&i!=j)continue;
                vec[i].push_back(j);
            }
        }
        slove();
        printf("%d\n",ans);
    }
    return 0;
}


相关文章推荐

【图论】[POJ 2942]Knights of the Round Table

先找连通图,然后检查是否是二分图注意如果是在线的算法记得要清空Color数组因为存在一种情况儿子中含有两个连通图,那么自己儿子中就会存在一个割点已经被染了色,就有可能存在冲突。#include #i...

poj 2942 Knights of the Round Table 【无向图求BCC + 黑白染色判断二分图】

Knights of the Round Table Time Limit: 7000MS   Memory Limit: 65536K Total Submissions: 10700 ...

【连通图|双连通+二分图判定】POJ-2942 Knights of the Round Table

Knights of the Round Table

【poj2942】圆桌骑士Knights of the Round Table【双连通分量】【二分图】【奇圈】

传送门:http://poj.org/problem?id=2942 尽管我承认这题我几乎是对着书抄的代码(因为我还不熟- -),但是我还是WA了三次- -数组又没清零。 基本思想就是: 首先把...

POJ 2942 - Knights of the Round Table(点双联通+二分图)

题目: http://poj.org/problem?id=2942 题意: n个人参加会议,每次圆桌会议至少有三个人参加,互相憎恨的勇士不能坐在圆桌旁的相邻位置. 给出m组(a, b), 表...

POJ 2942 Knights of the Round Table (点-双连通分量 + 交叉法染色判二分图)

POJ 2942 Knights of the Round Table  链接:http://poj.org/problem?id=2942 题意:亚瑟王要在圆桌上召开骑士会议,为了不引发...
  • SIOFive
  • SIOFive
  • 2014年09月01日 16:48
  • 717

poj 2942 Knights of the Round Table(补图的求取+双连通分量+奇环的判断)

题目链接: 点击打开链接 题目大意: 给出一些骑士,他们之间有的人相互厌恶,不能挨着坐,如果一个骑士不能在任何一个奇环中出现,那么他要被剔除,问最少踢掉多少骑士 题目分析: 首先我们这些...

POJ2942 Knights of the Round Table(双联通分量+奇圈判断)

题目大意:有n个骑士要开会,有m对仇恨关系,可以坐很多张圆桌,每张圆桌至少三个人。求有多少个骑士不能参加会议,满足以下条件:1、相互憎恨的骑士不能相邻 2、出席会议的骑士必须是奇数 思路:既然给出...
  • cqbzwja
  • cqbzwja
  • 2015年07月21日 20:49
  • 324

【POJ】2942 Knights of the Round Table 点双连通经典题

Knights of the Round Table Time Limit: 7000MS   Memory Limit: 65536K Total Submissio...
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:【综合图论】PKU-2942-Knights of the Round Table
举报原因:
原因补充:

(最多只允许输入30个字)