题目
A path with no repeated vertices of an undirected graph is called a simple path. Given an undirected graph and two verteices S and D, return the number of vertics which don't lie on any simple paths between S and D.
Input
The input contains multiple test cases.
Each case starts with a line of four integers, N(1 < N ≤ 100), M(1 ≤ M ≤ N(N - 1) / 2), S(0 ≤ S < N), D(0 ≤ D < N). N is the number of vertices, M is the number of edges, S and D are two different vertices. Then M lines follow, each line contains two different integers A(0 ≤ A < N) and B(0 ≤ B < N), which represents an edge of the graph. It's ensure that there is at least one simple path between S and D.
Output
Output the number of such vertics, one line per case.
Sample Input
4 3 0 2 0 1 1 2 1 3 4 4 0 2 0 1 1 2 1 3 2 3
Sample Output
1 0
题意
给你一个无向图,simple path的意思是一条没有重复点的路径,问你不在从 s 到 t 的所有简单路径的点有多少个。
分析
将0--(n-1),每个点都删除一次,如果在删除某个点的时候,有的点突然不与s或不与 t 相连了,那么这个点一定不是在simple path上的点。需要注意的是,在每次删点的时候,都需要重新建立并查集(除了那个被删的点)。还有就是要先用vis数组标记,不能直接计数,避免重复。
代码
#include<iostream>
#include<cstdio>
#include<string.h>
using namespace std;
const int N=105;
int pre[N];
bool vis[N];
int a[N*N],b[N*N];
int find(int x)
{
int r=x;
while(r!=pre[r])
r=pre[r];
int tmp,a=x;
while(a!=r)
{
tmp=pre[a];
pre[a]=r;
a=tmp;
}
return r;
}
void unionn(int x,int y)
{
int rx=find(x);
int ry=find(y);
if(rx!=ry)
pre[ry]=rx;
}
int main()
{
int n,m,s,t;
while(~scanf("%d%d%d%d",&n,&m,&s,&t))
{
for(int i=0;i<m;i++)
scanf("%d%d",&a[i],&b[i]);
memset(vis,0,sizeof(vis));
for(int i=0;i<n;i++)//i表示每次删除的点
{
for(int j=0;j<=n;j++)
pre[j]=j;
for(int j=0;j<m;j++)//每次删点之后,重新建立并查集
{
if(a[j]!=i&&b[j]!=i)
unionn(a[j],b[j]);
}
for(int j=0;j<n;j++)
{
if(j!=i&&find(j)!=find(s)&&find(j)!=find(t))
vis[j]=1; //标记
}
}
int ans=0;
for(int i=0;i<n;i++)//计数
{
if(vis[i])
ans++;
}
printf("%d\n",ans);
}
return 0;
}