• bzoj 1574: [Usaco2009 Jan]地震损坏Damage


    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


    Sample Output

    3

    HINT

    牛棚2遭到损坏,导致牛棚2, 3, 4里面的牛无法回到农庄.

    解题:从1点往外bfs即可,显然答案的补集中的点 Vc的任何一个相连的点都不可能是给出的点

     1 #include<iostream>
     2 #include<cstdio>
     3 #include<cstring>
     4 #include<queue>
     5 #define maxn 400009
     6 using namespace std;
     7 int head[maxn],nex[maxn],point[maxn],now = 0,visit[maxn];
     8 int a[maxn];
     9 void add(int x,int y)
    10 {
    11     nex[++now] = head[x];
    12     head[x] = now;
    13     point[now] = y;
    14 }
    15 int bfs(int s)
    16 {
    17     queue<int>q;
    18     q.push(s);
    19     visit[s] = 1;
    20     int cnt = 0;
    21     while(!q.empty())
    22     {
    23         int u = q.front(),flag = 0;
    24         q.pop();
    25         for(int i = head[u]; i; i = nex[i])
    26         {
    27             int u = point[i];
    28             if(a[u])
    29             {
    30                 flag = 1;
    31                 break;
    32             }
    33         }
    34         if(flag)continue;
    35         cnt++;
    36         for(int i = head[u];i;i=nex[i])
    37         {
    38             int k = point[i];
    39             if(visit[k])continue;
    40             visit[k] = 1;
    41             q.push(k);
    42         }
    43     }
    44     return cnt;
    45 }
    46 int main()
    47 {
    48     int p,c,n,x,y;
    49     scanf("%d%d%d",&p,&c,&n);
    50     for(int i=1;i<=c;i++)
    51     {
    52         scanf("%d%d",&x,&y);
    53         add(x,y);
    54         add(y,x);
    55     }
    56     for(int i=1;i<=n;i++)
    57     {
    58         scanf("%d",&x);
    59         a[x] = 1;
    60     }
    61     int u = bfs(1);
    62     printf("%d
    ",p-u);
    63     return 0;
    64 }
  • 相关阅读:
    c#中String跟string的“区别”<转>
    JS中判断对象是否为空
    report builder地址:http://localhost/reports
    今天开始,主攻MS Dynamics CRM
    IO负载高的来源定位
    ORACL学习笔记 之 分区表
    Linux自动删除n天前日志
    Oracle中NVL2 和NULLIF的用法
    Ubuntu学习笔记之Sqldeveloper安装
    给ubuntu的swap分区增加容量
  • 原文地址:https://www.cnblogs.com/philippica/p/4890668.html
Copyright © 2020-2023  润新知