poj2942 点双连通分量

来源:互联网 发布:java如何控制并发 编辑:程序博客网 时间:2024/05/13 09:41
#include <stdio.h>
#include <string.h>

#define MAXN 1100
#define MAXM 1000100
#define MIN(a, b) ((a) < (b) ? (a) : (b))

struct EDGE{
int to, next;
}edges[MAXM];

int map[MAXN][MAXN], ans[MAXN][MAXN], dfn[MAXN], low[MAXN],total, top, n, times, res;
int strack[MAXN], colour[MAXN], can[MAXN];

void dfs(int u){
dfn[strack[top++] = u] = low[u] = ++times;
for(int i = 1; i <= n; i ++)
if(!map[u][i] && i != u)
if(dfn[i]) low[u] = MIN(low[u], dfn[i]);
else{
dfs(i);
low[u] = MIN(low[u], low[i]);
if(dfn[u] <= low[i]){
for(strack[top] = -1, ans[total][0] = u, res = 1; strack[top]!= i; ans[total][res ++] = strack[--top]);
if(res > 2)
ans[total++][res++] = -1;
}
}
}

void tarjan(){
int i;
times = top = total = 0;
memset(dfn, 0, sizeof(dfn));
for(i = 1; i <= n; i ++)
if(!dfn[i]) dfs(i);
}

void drow(int fa, int now, int co){
if(res) return;
for(int i = 1; i <= n; i ++)
if(!map[now][i] && now != i&& i != fa&& colour[i])
if(colour[i] == 1){
colour[i] = 5 - co;
drow(now, i, 5 - co);
}
else 
if(colour[i] == colour[now]){res = 1; return;}
}

void set_colour(int t){
int k = 0;
while(ans[t][k] != -1)
colour[ans[t][k ++]] = 1;
colour[ans[t][0]] = 2;
res = 0;
drow(-1, ans[t][0], 2);
k = 0;
while(ans[t][k] != -1){
colour[ans[t][k]] = 0;
if(res) can[ans[t][k]] = 1;
++k;
}
}

int Get_ans(){
int i, ans = 0;
memset(can, 0, sizeof(can));
memset(colour, 0, sizeof(colour));
for(i = 0; i < total; i ++)
set_colour(i);
for(i = 1; i <= n; i ++)
if(!can[i]) ans ++;
return ans;
}


int main(){
int m, i, x, y;int a[10], now = 5;
while(~scanf("%d %d", &n, &m),n){
memset(map, 0, sizeof(map));
for(i = 0; i < m; i ++){
scanf("%d %d", &x, &y);
map[x][y] = map[y][x] = 1;
}
tarjan();
printf("%d\n", Get_ans());
}
return 0;
}


原创粉丝点击