• BZOJ1574: [Usaco2009 Jan]地震损坏Damage


    有n个点m条边的无向图,s个信息表示点Ai没被损坏,且到点1的路径无法只经过“未损坏的点”,求到点1路径必经“损坏的点”的点的个数的最小值。

    初看毫无头绪,画个图模拟下,1--2(--5--6)--3--4,点4和6发出信息,那么有两种方式安排“损坏的点”:点2,或者点5和点3,显然后者答案更小

    也就是说,一个点如果发出信息,那么他到1所有的路径中的第一个点置“损坏”,可以使答案最小。

    ps:一个点到1必经损坏的点,2种情况:要么它自己损坏,要么与他连边的所有点到点1都必经损坏的点。

    因此就把发出信息的每个点和与它连边的点都标记,最后bfs一次找答案的补集拿总数减掉即可。

     1 #include<cstdio>
     2 #include<cstdlib>
     3 #include<algorithm>
     4 #include<cstdlib>
     5 #include<cstring>
     6 //#include<iostream>
     7 using namespace std;
     8 
     9 int n,m,s;
    10 #define maxn 30011
    11 #define maxm 200011
    12 struct Edge{int to,next;};
    13 struct Graph
    14 {
    15     Edge edge[maxm];int le;
    16     struct Node
    17     {
    18         int first;bool vis;
    19         Node() {first=vis=0;}
    20     }a[maxn];
    21     Graph() {le=2;}
    22     void add_edge(int x,int y)
    23     {
    24         edge[le].to=y;
    25         edge[le].next=a[x].first;
    26         a[x].first=le++;
    27     }
    28     void insert(int x,int y)
    29     {
    30         add_edge(x,y);
    31         add_edge(y,x);
    32     }
    33     void mark(int x)
    34     {
    35         a[x].vis=1;
    36         for (int i=a[x].first;i;i=edge[i].next)
    37             a[edge[i].to].vis=1;
    38     }
    39     int que[maxn],head,tail;
    40     int bfs()
    41     {
    42         que[head=(tail=1)-1]=1;
    43         a[1].vis=1;
    44         int ans=1;
    45         while (head!=tail)
    46         {
    47             const int now=que[head++];
    48             for (int i=a[now].first;i;i=edge[i].next)
    49                 if (!a[edge[i].to].vis)
    50                 {
    51                     que[tail++]=edge[i].to;
    52                     ans++;
    53                     a[edge[i].to].vis=1;
    54                 }
    55         }
    56         return ans;
    57     }
    58 }G;
    59 int x,y;
    60 int main()
    61 {
    62     scanf("%d%d%d",&n,&m,&s);
    63     for (int i=1;i<=m;i++)
    64     {
    65         scanf("%d%d",&x,&y);
    66         G.insert(x,y);
    67     }
    68     for (int i=1;i<=s;i++)
    69     {
    70         scanf("%d",&x);
    71         G.mark(x);
    72     }
    73     printf("%d
    ",n-G.bfs());
    74     return 0;
    75 }
    View Code
  • 相关阅读:
    实验二 Nmap的实践
    《网络攻击与防范》第八周学习总结
    《网络攻击与防范》第七周学习总结
    《网络攻击与防范》第六周学习总结
    《网络攻击与防范》第五周学习总结
    《网络攻击与防范》第四周学习总结
    《网络攻击与防范》第三周学习总结
    《网络攻击与防范》第二周学习总结
    Linux 基础入门学习总结
    20169312 2016-2017-2《网络攻防实践》课程总结
  • 原文地址:https://www.cnblogs.com/Blue233333/p/7149614.html
Copyright © 2020-2023  润新知