标签: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