【bzoj1574/Usaco2009 Jan】地震损坏Damage——dfs
Description
农夫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接到所有短信之后,找出最小的不可能回到农庄的牛棚数目.这个数目包括损坏的牛棚. 注意:前50次提交将提供在一些测试数据上的运行结果.
Input
* 第1行: 三个空格分开的数: P, C, 和 N
* 第2..C+1行: 每行两个空格分开的数: a_i 和 b_i * 第C+2..C+N+1行: 每行一个数: report_j
Output
* 第1行: 一个数,最少不能回到农庄的牛的数目(包括损坏的牛棚).
Sample Input
4 3 1
1 2
2 3
3 4
3
1 2
2 3
3 4
3
Sample Output
3
HINT
牛棚2遭到损坏,导致牛棚2, 3, 4里面的牛无法回到农庄.
主要是题目翻译(好像)有问题,应该是不能通过没有损坏的点。
那就直接打完标记从1开始dfs统计答案就行啦。
代码:
1 #include<cstdio> 2 #include<cstring> 3 #include<queue> 4 #include<algorithm> 5 #define mem(a,p) memset(a,p,sizeof(a)) 6 const int N=1e5+10; 7 struct node{int ne,to;}e[N*2]; 8 int first[N],p,n,c,tot=0,ans; 9 bool ok[N],flag[N]; 10 int read(){ 11 int ans=0,f=1;char c=getchar(); 12 while(c<'0'||c>'9'){if(c=='-')f=-1;c=getchar();} 13 while(c>='0'&&c<='9'){ans=ans*10+c-48;c=getchar();} 14 return ans*f; 15 } 16 void ins(int u,int v){e[++tot]=(node){first[u],v};first[u]=tot;} 17 void del(int x){ 18 for(int i=first[x];i;i=e[i].ne)flag[e[i].to]=1; 19 } 20 void dfs(int x){ 21 ok[x]=1;ans--; 22 for(int i=first[x];i;i=e[i].ne){ 23 int to=e[i].to; 24 if(!ok[to]&&!flag[to])dfs(to); 25 } 26 } 27 int main(){ 28 p=read();c=read();n=read(); 29 for(int i=1,a,b;i<=c;i++){ 30 a=read();b=read();ins(a,b);ins(b,a); 31 } 32 for(int i=1,a;i<=n;i++){ 33 a=read();del(a); 34 } 35 ans=p; 36 dfs(1); 37 printf("%d\n",ans); 38 return 0; 39 }