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

题目链接

  1 #include <iostream>
  2 #include <cstring>
  3 #include <cstdio>
  4 #include <algorithm>
  5 #include <stack>
  6 #include <vector>
  7 using namespace std;
  8 const int Max = 1010;
  9 vector<int> G[Max], bcc[Max];
 10 int odd[Max], color[Max];
 11 int A[Max][Max];
 12 int pre[Max], iscut[Max], bccno[Max];
 13 int dfs_clock, bcc_cnt;
 14
 15 struct Edge
 16 {
 17     int u, v;
 18 };
 19 stack<Edge> S;
 20 int dfs(int u, int fa)
 21 {
 22     int lowu = pre[u] = ++dfs_clock;
 23     int child = 0;
 24     int Size = (int) G[u].size();
 25     for (int i = 0; i < Size; i++)
 26     {
 27         int v = G[u][i];
 28         Edge e;
 29         e.u = u;
 30         e.v = v;
 31         if (!pre[v])
 32         {
 33             S.push(e);
 34             child++;
 35             int lowv = dfs(v, u);
 36             lowu = min(lowu, lowv);
 37             if (lowv >= pre[u])
 38             {
 39                 iscut[u] = true;
 40                 ++bcc_cnt;
 41                 bcc[bcc_cnt].clear();
 42                 for(;;)
 43                 {
 44                     Edge x = S.top();
 45                     S.pop();
 46                     if (bccno[x.u] != bcc_cnt)
 47                     {
 48                         bcc[bcc_cnt].push_back(x.u);
 49                         bccno[x.u] = bcc_cnt;
 50                     }
 51                     if (bccno[x.v] != bcc_cnt)
 52                     {
 53                         bcc[bcc_cnt].push_back(x.v);
 54                         bccno[x.v] = bcc_cnt;
 55                     }
 56                     if (x.u == u && x.v == v)
 57                         break;
 58                 }
 59             }
 60         }
 61         else if (pre[v] < pre[u] && v != fa)
 62         {
 63             S.push(e);
 64             lowu = min(lowu, pre[v]);
 65         }
 66     }
 67     if (fa < 0 && child == 1)
 68         iscut[u] = false;
 69     return lowu;
 70 }
 71 void find_bcc(int n)
 72 {
 73     memset(pre, 0, sizeof(pre));
 74     memset(iscut, 0, sizeof(iscut));
 75     memset(bccno, 0, sizeof(bccno));
 76     dfs_clock = bcc_cnt = 0;
 77     for (int i = 0; i < n; i++)
 78     {
 79         if (!pre[i])
 80             dfs(i, -1);
 81     }
 82 }
 83 bool bipartite(int u, int b)
 84 {
 85     for (int i = 0; i < (int) G[u].size(); i++)
 86     {
 87         int v = G[u][i];
 88         if (bccno[v] != b)
 89             continue;
 90         if (color[v] == color[u])
 91             return false;
 92         if (!color[v])
 93         {
 94             color[v] = 3 - color[u];
 95             if (!bipartite(v, b))
 96                 return false;
 97         }
 98     }
 99     return true;
100 }
101 int main()
102 {
103     int n, m;
104     while (scanf("%d%d", &n, &m) != EOF)
105     {
106         if (n == 0 && m == 0)
107             break;
108         for (int i = 0; i <= n; i++)
109             G[i].clear();
110         memset(A, 0, sizeof(A));
111         for (int i = 0; i < m; i++)
112         {
113             int u, v;
114             scanf("%d%d", &u, &v);
115             u--;
116             v--;
117             A[u][v] = A[v][u] = 1;
118         }
119         for (int i = 0; i < n; i++)
120         {
121             for (int j = i + 1; j < n; j++)
122             {
123                 if (!A[i][j])
124                 {
125                     G[i].push_back(j);
126                     G[j].push_back(i);
127                 }
128             }
129         }
130
131         find_bcc(n);
132
133        // cout << bcc[3][0] << endl;
134         memset(odd, 0, sizeof(odd));
135         for (int i = 1; i <= bcc_cnt; i++)
136         {
137             memset(color, 0, sizeof(color));
138             for (int j = 0; j < (int) bcc[i].size(); j++)
139                 bccno[ bcc[i][j] ] = i;
140             int u = bcc[i][0];
141             color[u] = 1;
142
143             if (!bipartite(u, i))
144             {
145                 for (int j = 0; j < (int) bcc[i].size(); j++)
146                     odd[ bcc[i][j] ] = 1;
147             }
148         }
149         int ans = n;
150         for (int i = 0; i < n; i++)
151             if (odd[i])
152             ans--;
153         printf("%d\n", ans);
154     }
155     return 0;
156 }

时间: 2024-10-29 20:13:55

POJ 2942Knights of the Round Table(二分图判定+双连通分量)的相关文章

poj 2942 Knights of the Round Table(无向图的双连通分量+二分图判定)

#include<cstdio> #include<cstring> #include<cmath> #include<cstdlib> #include<iostream> #include<algorithm> #include<vector> #include<map> #include<queue> #include<stack> #include<string> #

POJ_2942_Knights of the Round Table(点的双连通分量+二分图判定)

Knights of the Round Table Time Limit: 7000MS   Memory Limit: 65536K Total Submissions: 10908   Accepted: 3585 Description Being a knight is a very attractive career: searching for the Holy Grail, saving damsels in distress, and drinking with the oth

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

POJ 2942 Knights of the Round Table 链接:http://poj.org/problem?id=2942 题意:亚瑟王要在圆桌上召开骑士会议,为了不引发骑士之间的冲突,并且能够让会议的议题有令人满意的结果,每次开会前都必须对出席会议的骑士有如下要求: 1. 相互憎恨的两个骑士不能坐在直接相邻的2个位置: 2. 出席会议的骑士数必须是奇数,这是为了让投票表决议题时都能有结果. 如果出现有某些骑士无法出席所有会议(例如这个骑士憎恨所有的其他骑士),则亚瑟王为了世界和

POJ 2942 Knights of the Round Table (点双连通分量,偶图判定)

题意:多个骑士要开会,3人及以上才能凑一桌,其中部分人已经互相讨厌,肯定不坐在同一桌的相邻位置,而且一桌只能奇数个人才能开台.给出多个人的互相讨厌图,要求多少人开不成会(注:会议不要求同时进行,一个人开多个会不冲突)? 分析: 给的是互相讨厌的图,那么转成互相喜欢的吧,扫一遍,如果不互相讨厌就认为互相喜欢,矩阵转邻接表先. 有边相连的两个点代表能坐在一块.那么找出一个圈圈出来,在该圈内的点有奇数个人的话肯定能凑成1桌.圈圈?那就是简单环了,跟点双连通分量的定义好像一样:每个点都能同时处于1个及以

poj 2942--Knights of the Round Table (点的双连通分量)

做这题简直是一种折磨... 有n个骑士,骑士之间相互憎恨.给出骑士的相互憎恨的关系. 骑士要去开会,围成一圈坐,相互憎恨的骑士不能相邻.开会骑士的个数不能小于三个人.求有多少个骑士不能开会. 注意:会议可以开无数次,也就是说一个骑士其实是可以开多次会议的,所以一共可以开会的人也未必是奇数. 求出相互并不憎恨的骑士的关系图,也就是相连的骑士可以挨着.这样如果有一个奇数圈就可以确定一圈的人全部可以参加会议. 性质:如果一个双连通分量内的某些顶点在一个奇圈中(即双连通分量含有奇圈),那么这个双连通分量

UVA 1364 - Knights of the Round Table (找双连通分量 + 二分图染色法判断)

都特么别说话,我先A了这道题! 卧槽啊.....! 题意来自 kuangbin: 亚瑟王要在圆桌上召开骑士会议,为了不引发骑士之间的冲突, 并且能够让会议的议题有令人满意的结果,每次开会前都必须对出席会议的骑士有如下要求: 1.  相互憎恨的两个骑士不能坐在直接相邻的2个位置: 2.  出席会议的骑士数必须是奇数,这是为了让投票表决议题时都能有结果. 注意:1.所给出的憎恨关系一定是双向的,不存在单向憎恨关系. 2.由于是圆桌会议,则每个出席的骑士身边必定刚好有2个骑士. 即每个骑士的座位两边都

UVALive - 3523 Knights of the Round Table(无向图的双连通分量)

题目大意:有n个骑士经常举行圆桌会议,每次圆桌会议至少要有3个骑士参加(且每次参加的骑士数量是奇数个),且所有互相憎恨的骑士不能坐在圆桌旁的相邻位置,问有多少个骑士不可能参加任何一个会议 解题思路:以骑士为点建立无向图G.如果两个骑士可以相邻(即他们并不互相憎恨),即可连一条边. 则题目就转化为求不在任何一个简单奇圈上的结点个数 首先,圈就是一个双连通的分量,所以第一件事就是将所有的双连通分量求出来,接着再判定这个双连通分量是不是奇圈 奇圈的判定就是用二分图染色判定,如果某个圈能被二分图染色,那

UVALive3523-Knights of the Round Table(BCC+二分图判定)

题目链接 题意:有n个骑士经常举行圆桌会议,每次至少3人参加,且相互厌恶的其实不能坐在圆桌相邻的位置.如果发生意见分歧,则要举手表决,因此参加的骑士数目一定要为奇数.统计有多少人不能参加任何一个会议. 思路:这是大白上面的一道例题.我们可以先根据骑士之间的关系建立无向图G,则题目就转化为求不再任何一个简单奇圈上的结点个数.如果图G不连通,就分别对G的连通分量求解.简单圈上的所有结点必然属于同一个双连通分量,因此我们只要求出所有的双连通分量.但是二分图是不存在奇圈的,所以我们只需要关注那些不是二分

UVALive-3523 Knights of the Round Table (双连通分量+二分图匹配)

题目大意:有n个骑士要在圆桌上开会,但是相互憎恶的两个骑士不能相邻,现在已知骑士们之间的憎恶关系,问有几个骑士一定不能参加会议.参会骑士至少有3个且有奇数个. 题目分析:在可以相邻的骑士之间连一条无向边,构成一张图G.则问题变成了有几个节点不在奇圈(有奇数个节点的圈)内,并且一个点在圈内最多出现一次.如果G不连通,应该对每一个分量分别求解.奇圈上的点一定在同一个双连通分量内,要找出所有的双连通分量.但是能构成二分图的双连通分量中一定没有奇圈,不能构成二分图的双连通分量中一定含有奇圈,并且分量中所