割点水题。。图论题基本就是套模板。。PS:输入有点点恶心,最讨厌的就是处理这中麻烦的输入了。。直接给出来明白的多。
#include <stdio.h>
#include <string.h>
const int N = 105;
int g[N][N];
int color[N], d[N], low[N];//color[]记录点的颜色 0:白色 1:灰色 2:黑色
bool cut[N];//d[]记录点的深度。low[]记录每个节点相连点的最小深度(最高祖先的深度),cut[]记录割点
void dfs(int k, int father, int deep, int n)
{
int tot = 0;
color[k] = 1;
d[k] = low[k] = deep;
for(int i = 1; i <= n; i++)
{
if(!g[k][i]) continue;
int t = i;
if(t != father && color[t] == 1)
low[k] = low[k] < d[t] ? low[k] : d[t];
if(color[t] == 0)
{
dfs(t, k, deep + 1, n);
tot++;
low[k] = low[k] < low[t] ? low[k] : low[t];
if((k == 1 && tot > 1) || (k != 1 && low[t] >= d[k]))
cut[k] = 1;
}
}
color[k] = 2;
}
char data[1005];
int main()
{
int n, a[N];
while(scanf("%d", &n), n)
{
gets(data);
memset(g, 0, sizeof(g));
memset(cut, 0, sizeof(cut));
memset(color, 0, sizeof(color));
while(gets(data), strcmp(data, "0"))
{
int l = strlen(data);
int b = 0, top = 0;
for(int i = 0; i < l; i++)
{
if(data[i] >= '0' && data[i] <= '9') b = b * 10 + data[i] - '0';
if(i + 1 == l || data[i + 1] == ' ')
{
// printf("b = %d\n", b);
a[top++] = b;
b = 0;
}
}
for(int i = 1; i < top; i++)
g[a[0]][a[i]] = g[a[i]][a[0]] = 1;
}
dfs(1, 0, 0, n);
int sum = 0;
for(int i = 1; i <= n; i++)
{
if(cut[i]) sum++;
}
printf("%d\n", sum);
}
return 0;
}