关闭

poj2942圆桌骑士【点双连通分量+二分图判断】

标签: poj点双连通分量二分图
581人阅读 评论(0) 收藏 举报
分类:
/***********
poj2942
2015.11.11-2015.11.13
不懂 暂时放下了
2015.11.18
4792K	1172MS	G++
***********/
#include <iostream>
#include<cstdio>
#include<cstring>
#include<vector>
#include<stack>
#include<algorithm>
using namespace std;
#define maxn 1005
struct Edge
{
    int u,v;
};
int pre[maxn],iscut[maxn],bccno[maxn],dfs_clock,bcc_cnt;//pre[]表示开始时间 bccno[]表示某点所在集合号 bcc_cnt表示编号
vector<int>G[maxn],bcc[maxn];
stack<Edge>S;
int dfs(int u,int fa)
{
    int lowu=pre[u]=++dfs_clock;//记录访问时间
    int child=0;
    for(int i=0;i<G[u].size();i++)//遍历与u点相连接的边
    {
        int v=G[u][i];
        Edge e=(Edge){u,v};//当前的点所连接的边
        if(!pre[v])
        {
            S.push(e);
            child++;
            int lowv=dfs(v,u);//后代
            lowu=min(lowu,lowv);//用后代的low函数更新自己
            if(lowv>=pre[u])//存在子节点连不回此点之前的点,此点是割点--定理
            {
                iscut[u]=true;//标记为割点
                bcc_cnt++;
                bcc[bcc_cnt].clear();
                for(;;)
                {
                    Edge x=S.top();S.pop();
                    if(bccno[x.u]!=bcc_cnt)
                    {
                        bcc[bcc_cnt].push_back(x.u);
                        bccno[x.u]=bcc_cnt;
                    }
                    if(bccno[x.v]!=bcc_cnt)//防止加重
                    {
                        bcc[bcc_cnt].push_back(x.v);
                        bccno[x.v]=bcc_cnt;
                    }
                    if(x.u==u&&x.v==v) break;
                }
            }
        }
        else if(pre[v]<pre[u]&&v!=fa)//访问过v 而且v在u之前
        {
            S.push(e);
            lowu=min(lowu,pre[v]);//用反向边更新自己
        }
    }
    if(fa<0&&child==1) iscut[u]=0;//判断是根节点而且只有一个孩子那么不是割顶
    return lowu;//返回后代序号
}
void find_bcc(int n){
    memset(pre,0,sizeof(pre));
    memset(iscut,0,sizeof(iscut));
    memset(bccno,0,sizeof(bccno));
    dfs_clock=bcc_cnt=0;
    for(int i=0;i<n;i++)
        if(!pre[i]) dfs(i,-1);
}
int odd[maxn],color[maxn];
bool bipartite(int u,int b)//判断是否是二分图
{
    for(int i=0;i<G[u].size();i++)//遍历与这个点相连接的点
    {
        int v=G[u][i];
        if(bccno[v]!=b) continue;//不在同一个连通分量 跳过
        if(color[v]==color[u]) return false;
        if(!color[v])//此点未遍历过
        {
            color[v]=3-color[u];//此点颜色等于三减去与此点相连点的颜色
            if(!bipartite(v,b)) return false;
        }
    }
    return true;
}
int A[maxn][maxn];
int main()
{
    int kase=0,n,m;
    while(scanf("%d%d",&n,&m)==2&&n)
    {
        for(int i=0;i<n;i++) G[i].clear();
        memset(A,0,sizeof(A));
        for(int i=0;i<m;i++)
        {
            int u,v;
            scanf("%d%d",&u,&v);
            u--;v--;
            A[u][v]=A[v][u]=1;
        }
        for(int u=0;u<n;u++)
        {
            for(int v=u+1;v<n;v++)
                if(!A[u][v])
                {
                    G[u].push_back(v);
                    G[v].push_back(u);
                }
        }
        find_bcc(n);
        memset(odd,0,sizeof(odd));
        //题目要求不在任何一个简单奇圈上的节点个数
        for(int i=1;i<=bcc_cnt;i++)
        {
            memset(color,0,sizeof(color));
            for(int j=0;j<bcc[i].size();j++)
                bccno[bcc[i][j]]=i;//主要处理割顶
            int u=bcc[i][0];
            color[u]=1;//u是这个连通分量的第一个点
            if(!bipartite(u,i))//如果某个连通分量不是二分图
                for(int j=0;j<bcc[i].size();j++)
                    odd[bcc[i][j]]=1;//给其中所有节点标记在奇圈上
        }
        int ans=n;
        for(int i=0;i<n;i++) if(odd[i]) ans--;
        printf("%d\n",ans);
    }
    return 0;
}
二分图的求法有待考究
0
0
查看评论

poj2942圆桌骑士(点双连通分量+二分图染色法判奇圈)

之前一直不明白点双连通分量能用来干嘛,比如边双连通分量可以问加几条边能变成边双连通,这个题目是这样的,每个圆桌会议至少三个骑士参加,因为需要表决意见,所以骑士数目必须是奇数个,直到那些骑士互相憎恨,也就是不能坐在一起的,把能坐在一起的建边,求无法参加任何会议的骑士的个数,重点是任何会议,这点非常关键...
  • zcmartin2014214283
  • zcmartin2014214283
  • 2016-05-10 22:03
  • 953

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

传送门:http://poj.org/problem?id=2942 尽管我承认这题我几乎是对着书抄的代码(因为我还不熟- -),但是我还是WA了三次- -数组又没清零。 基本思想就是: 首先把不互相憎恨的骑士连边。 求双连通分量bcc。 判断每个bcc是不是二分图,是的话这个二分图里的骑...
  • ZMOIYNLP
  • ZMOIYNLP
  • 2015-03-03 16:54
  • 794

poj2942 圆桌骑士

题目大意:给定n个骑士以及m个讨厌关系,让你找到满足以下关系的需要减去骑士的最少数: 1、每个骑士的两边必须是自己的朋友! 2、每个桌子上必须坐奇数个人,这就意味着必须转化为一个奇圈,如果一个骑士不能和其它骑士组成一个奇圈则除去,并且一个人则也除去,因为一个人不能坐一个桌子! 解题思路: 首...
  • xuezhongfenfei
  • xuezhongfenfei
  • 2013-03-22 23:33
  • 764

poj 2942-圆桌骑士(点双连通分量+二分图)

题目:http://poj.org/problem?id=2942 题意: 一群骑士,某些骑士之间互相憎恨,如果在一起容易发生争斗事件,因此他们只有满足一定条件才能参加圆桌会议:1.圆桌边上任意相邻的两个骑士不能互相憎恨;2。同一个圆桌边上的骑士数量必须是奇数; 分析: 这题训练指南上有详...
  • hjt_fathomless
  • hjt_fathomless
  • 2016-10-02 15:47
  • 219

POJ 2942 圆桌骑士问题。

Knights of the Round Table Time Limit: 7000MS   Memory Limit: 65536K Total Submissions: 8785   Accepted: 2813 Description Being a ...
  • u012358934
  • u012358934
  • 2014-01-18 18:57
  • 864

LA3523.Knights of the Round Table圆桌骑士——点双连通分量+二分图判断

http://www.bnuoj.com/v3/problem_show.php?pid=3061题目描述: 有n个骑士经常举行圆桌会议,商讨大事。每次圆桌会议至少应有3个骑士参加,且相互憎恨的骑士不能坐在圆桌旁的相邻位置。如果发生意见分歧,则需要举手表决,因此参加会议的骑士数目必须是奇数,以防止...
  • u014141559
  • u014141559
  • 2015-04-25 12:10
  • 579

UVALive 3523 圆桌骑士

题目大意:有n个骑士经常举行圆桌会议,每次圆桌会议至少要有3个骑士参加(且每次参加的骑士数量是奇数个),且所有互相憎恨的骑士不能坐在圆桌旁的相邻位置,问有多少个骑士不可能参加任何一个会议思路,首先根据给出的憎恨图得出补图,然后就是找出不能形成奇圈的点 利用下面二个定理: 1.如果一个双连通分量的某些...
  • cquzhengdayday
  • cquzhengdayday
  • 2016-09-02 15:26
  • 184

例题5.5 圆桌骑士 LA3523

1.题目描述:点击打开链接 2.解题思路:本题利用二分图+双连通分量解决。首先,可以把所有相互之间不憎恨的骑士连接一条无向边,那么题目转化为在这个无向图中有多少个结点不在任何一个简单奇圈上。这里的“简单奇圈”指的是圈上顶点个数为奇数,且每个结点只会出现在一个圈中。简单圈上的点一定属于同一个双连通分...
  • u014800748
  • u014800748
  • 2015-09-30 23:10
  • 406

POJ 2942 圆桌骑士 点双连通+二分图判定

#include #include #include #include #include #include #include #include #define N 1005 #define M 1000005 using namespace std; struct Edge{ int from,...
  • qq574857122
  • qq574857122
  • 2014-01-14 19:10
  • 1385

UVa Problem 10195 The Knights of the Round Table (圆桌骑士)

// The Knights of the Round Table (圆桌骑士) // PC/UVa IDs: 111303/10195, Popularity: A, Success rate: average Level: 2 // Verdict: Accepted // Submission...
  • metaphysis
  • metaphysis
  • 2011-11-10 01:00
  • 1605
    碎碎念
    周小姐,你还想毕业找不到工作吗????
    个人资料
    • 访问:279498次
    • 积分:8804
    • 等级:
    • 排名:第2603名
    • 原创:608篇
    • 转载:25篇
    • 译文:0篇
    • 评论:38条
    友情链接