标签:des style http color os io strong for ar
Description
Input
Output
Sample Input
5 5 1 4 1 5 2 5 3 4 4 5 0 0
Sample Output
2
Hint
题目大意:有n个骑士,m对人相互讨厌,现在要求相互讨厌的人不能坐一起开会,每桌上必须是>=3的奇数个人,最少几个人不能去参加任何一个会议,(会议可以不同的天举行)。
连接所有可能的边,将相互讨厌的去掉,剩余的就是可以相邻的坐在一起的,保证奇数个,就要求图中的双连通分量,不能是二分图,所以找出割点,将割点,将每一个双连通分量的点存下,用染色的方法,判断是不是二分图,最后得到要求的值
#include <cstdio> #include <cstring> #include <algorithm> #include <stack> #include <vector> using namespace std; #define maxn 2200 struct node{ int u , v ; int next ; } edge[2100000]; int head[maxn] , cnt , vis[2100000] ; int temp[maxn] , color[maxn] ; int dnf[maxn] , low[maxn] , time ; int Map[maxn][maxn] , ans[maxn] ; stack <int> sta; vector <int> vec[maxn] ; int num ; void init() { memset(head,-1,sizeof(head)); memset(vis,0,sizeof(vis)); memset(Map,0,sizeof(Map)); memset(dnf,0,sizeof(dnf)); memset(low,0,sizeof(low)); memset(temp,0,sizeof(temp)); memset(ans,0,sizeof(ans)); cnt = time = num = 0 ; } void add(int u,int v) { while( !sta.empty() ) sta.pop(); edge[cnt].u = u ; edge[cnt].v = v ; edge[cnt].next = head[u] ; head[u] = cnt++ ; edge[cnt].u = v ; edge[cnt].v = u ; edge[cnt].next = head[v] ; head[v] = cnt++ ; } void tarjan(int u) { dnf[u] = low[u] = ++time ; int i , j , v ; for(i = head[u] ; i != -1 ; i = edge[i].next) { if(vis[i]) continue ; vis[i] = vis[i^1] = 1 ; v = edge[i].v ; if( !dnf[v] ) { sta.push(i) ; tarjan(v); low[u] = min( low[u],low[v] ) ; if( low[v] >= dnf[u] ) { num++ ; vec[num].clear(); while(1) { j = sta.top(); sta.pop(); vec[num].push_back(edge[j].u); vec[num].push_back(edge[j].v); if( edge[j].u == u && edge[j].v == v ) break; } } } else if( dnf[v] < dnf[u] ) { sta.push(i) ; low[u] = min( low[u],dnf[v] ); } } } int dey(int u,int k) { int i ,v ; for(i = head[u] ; i != -1 ; i = edge[i].next) { v = edge[i].v ; if( temp[v] != k ) continue ; if( color[v] == color[u] ) return 0 ; if( !color[v] ) { color[v] = 3 - color[u] ; if( !dey(v,k) ) return 0 ; } } return 1 ; } int main() { int n , m , u , v , i , j ; while(scanf("%d %d", &n, &m) && (n+m) != 0 ) { init(); while(m--) { scanf("%d %d", &u, &v); Map[u][v] = Map[v][u] = 1 ; } for(i = 1 ; i <= n ; i++) for(j = i+1 ; j <= n ; j++) if( !Map[i][j] ) add(i,j); for(i = 1 ; i <= n ; i++) if( !dnf[i] ) tarjan(i); for(i = 1 ; i <= num ; i++) { if( vec[i].size() < 3 ) continue ; for(j = 0 ; j < vec[i].size() ; j++) temp[ vec[i][j] ] = i ; memset(color,0,sizeof(color)); u = vec[i][0] ; color[u] = 1 ; if( !dey(u,i) ) { for(j = 0 ; j < vec[i].size(); j++) ans[ vec[i][j] ] = 1 ; } } m = n ; for(i = 1 ; i <= n ; i++) if( ans[i] ) m-- ; printf("%d\n", m); } return 0; }
poj2924--F - Knights of the Round Table(圆桌骑士,经典连通分量)
标签:des style http color os io strong for ar
原文地址:http://blog.csdn.net/winddreams/article/details/38852363