题目描述
农夫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 }
原文地址:https://www.cnblogs.com/gzh01/p/9385256.html
时间: 2024-10-23 08:15:19