zoj3583Simple Path【并查集(思想很好)】

大意:

告诉你一个无向图

然后定义一个simple path是一条路径上面不包含重复的点

然后告诉你两个点s, t

问有多上个点是不在s到t的simple路径上

 

分析:

对于从s到t的simple path上  无论删除其他的任何一个 点   那么这个点一定是要么和s相连,要么和t相连

从这个角度出发的话

如果删除任何一点

如果有个点突然不和s,或t相连了

那么改点也就一定不是该simple path上的点

最后统计一下个数即可

 

代码:

 1 #include <iostream>
 2 #include <cstdio>
 3 #include <cstring>
 4 using namespace std;
 5 
 6 const int maxn = 105;
 7 int a[maxn * maxn], b[maxn * maxn];
 8 int vis[maxn];
 9 int fa[maxn];
10 
11 int Find(int i) {
12     if(fa[i] == i) return i;
13     return fa[i] = Find(fa[i]);
14 }
15 
16 void Union(int u, int v) {
17     int fu = Find(u); int fv = Find(v);
18     if(fu != fv) {
19         fa[fu] = fv;
20     }
21 }
22 
23 int main() {
24     int n, m, s, t;
25     while(EOF != scanf("%d %d %d %d",&n, &m, &s, &t) ) {
26         for(int i = 1; i <= m; i++) {
27             scanf("%d %d",&a[i], &b[i]);
28         }
29         memset(vis,0, sizeof(vis));
30         for(int i = 0; i < n; i++) {
31             for(int j = 0; j <= n; j++) fa[j] = j;
32             for(int j = 1; j <= m; j++) {
33                 if(a[j] != i && b[j] != i) {
34                     Union(a[j], b[j]);
35                 }
36             }
37             for(int j = 0; j < n; j++) {
38                 if(j != i && Find(j) != Find(s) && Find(j) != Find(t)) {
39                     vis[j] = 1;
40                 }
41             }
42         }
43         int ans = 0;
44         for(int i = 0; i < n; i++) {
45             if(vis[i]) {
46                    ans++;
47             }
48         }
49         printf("%d\n",ans);
50     }    
51     return 0;
52 }
View Code

 

posted @ 2014-09-19 21:00  悠悠我心。  阅读(558)  评论(0编辑  收藏  举报