自从区域赛以后就没参加浙大月赛这种比赛了
这题比赛的时候也没有过
有两种解法,这种是并查集
想象一下从s到t的一条简单路,想想简单路上每个点的性质:比如简单路上的点i,不管删去图上任何一个点,点i总会至少与s或t在一个相连的集合中
另外想想不在简单路上的点j,一定可以找到一个点,使得j与s和t都不在一个相连的集合中
用这种性质即可证明
#include <cstdio>
#include <cstring>
const int MAXN = 100 + 3;
int n, m, s, t;
int map[MAXN][MAXN];
int p[MAXN];
bool flag[MAXN];
void init()
{
for(int i = 0; i < n; i++) p[i] = i;
}
int find(int x)
{
if(x != p[x]) p[x] = find(p[x]);
return p[x];
}
void Union(int a, int b)
{
a = find(a);
b = find(b);
p[a] = b;
}
int main()
{
while(scanf("%d%d%d%d", &n, &m, &s, &t) != EOF)
{
memset(map, 0, sizeof(map));
memset(flag, 0, sizeof(flag));
int a, b;
for(int i = 0; i < m; i++)
{
scanf("%d%d", &a, &b);
map[a][b] = map[b][a] = 1;
}
for(int i = 0; i < n; i++)//一定需要s和t
{
init();
for(int j = 0; j < n; j++)
for(int k = j + 1; k < n; k++)
if(j != i && k != i && map[j][k])
{
Union(j, k);
}
for(int j = 0; j < n; j++)
if(j != i && find(j) != find(s) && find(j) != find(t))
flag[j] = 1;
}
int ans = 0;
for(int i = 0; i < n; i++)
if(flag[i]) ans++;
printf("%d\n", ans);
}
return 0;
}