【USACO 2009 JAN】地震造成的破坏Earthquake Damage(DFS)

题目描述

农夫John的农场遭受了一场地震。有一些牛棚遭到了损坏,但幸运地,所有牛棚间的路径都还能使用。 FJ的农场有P(1 <= P <= 30,000)个牛棚,编号1..P,C(1 <= C <= 100,000)条双向路径连接这些牛棚,编号为1..C,路径i连接牛棚a_i和b_i (1 <= a_i<= P;1 <= b_i <= P),路径可能连接a_i到它自己,两个牛棚之间可能有多条路径。农庄在编号为1的牛棚。N (1 <= N <= P)头在不同牛棚的牛通过手机短信report_j(2 <= report_j <= P)告诉FJ它们的牛棚(report_j)没有损坏,但是它们无法通过路径和没有损坏的牛棚回到到农场。当FJ接到所有短信之后,找出最小的不可能回到农庄的牛棚数目。这个数目包括损坏的牛棚。

输入

第1行: 三个空格分开的数: P, C, 和 N。

第2..C+1行: 每行两个空格分开的数: a_i 和 b_i * 第C+2..C+N+1行: 每行一个数: report_j。

输出

第1行: 一个数,最少不能回到农庄的牛的数目(包括损坏的牛棚)。

一个点如果无法到达,也就是说与它相连的所有点都无法到达,那么我们只需要将所有发短信的奶牛的农场标记一下即可。搜索时记录访问到的点,无法到达的点就是不可能回到农庄的牛棚和被破坏的牛棚。

 1 #include <cstdio>
 2 #include <vector>
 3   
 4 #define N 30001
 5   
 6 int p,c,n,a,b,r,ans;
 7 bool vis[N];
 8 std::vector<int> g[N];
 9   
10 void dfs(int u){
11     ++ans;
12     vis[u]=true;
13     for(int i=0;i<g[u].size();++i){
14         int v=g[u][i];
15         if(vis[v])continue;
16         dfs(v);
17     }
18 }
19   
20 int main(void){
21     scanf("%d%d%d",&p,&c,&n);
22     for(int i=1;i<=c;++i){
23         scanf("%d%d",&a,&b);
24         g[a].push_back(b);
25         g[b].push_back(a);
26     }
27     for(int i=1;i<=n;++i){
28         scanf("%d",&r);
29         for(int i=0;i<g[r].size();++i){
30             int v=g[r][i];
31             vis[v]=true;
32         }
33     }
34     dfs(1);
35     printf("%d",p-ans);
36 }

 

posted @ 2018-07-29 14:25  gzh01  阅读(384)  评论(0编辑  收藏  举报