• [USACO09MAR]地震损失2Earthquake Damage 2


    地震破坏

    时间限制: 1 Sec  内存限制: 128 MB

    题目描述

    威斯康星发生了一场地震!约翰的牧场遭到了打击,有一些牛棚变成了废墟,如果一间牛棚遭到
    了破坏,那么所有和它相连的道路都不能使用了。
    约翰有 N 个牛棚,编号为 1 到 N,有 M 条双向道路连接这些牛棚,第 i 条道路连接的牛棚是
    A i 和 B i ,A i 可能等于 B i ,也可能有多条道路连接同一对牛棚。
    约翰让奶牛们集中到 1 号牛棚避难。有 P 头奶牛通过手机向约翰求救,她们的遭遇类似:好消
    息是她们所在的牛棚没有损坏,坏消息是由于其他的牛棚遭到破坏,所以她们找不到任何可以走到 1
    号牛棚的路径。假设发送报告的第 i 头奶牛目前在牛棚 R i 里,那么以最乐观的情况来看,至少有多
    少牛棚被破坏了呢?

    输入

    • 第一行:三个整数 N,M 和 P, 1 ≤ P ≤ N ≤ 3000, 1 ≤ M ≤ 20000
    • 第二行到第 M + 1 行:第 i + 1 行有两个整数 A i 和 B i ,1 ≤ A i ,B i ≤ N
    • 第 M + 2 行到第 M + P + 1 行:第 i + M + 1 行有一个整数 R i , 1 ≤ R i ≤ N,保证每个 R i 都
    是不同的

    输出

    • 单个整数:表示至少有几个牛棚被破坏了

    样例输入

    5 5 2
    1 2
    2 3
    3 5
    2 4
    4 5
    4
    5

    样例输出

    1

    提示

    最乐观的情况是只有 2 号牛棚坏了

    题解:

    一道比较经典的最小割,首先因为每次删除的是一个点,所以要将每个点拆开,将1节点和打电话过来的几个节点残量设为最大值,其余的为1。(为了让割边落在可以去掉的点上)这样就可以将去点转化为割边。

    然后根据图的连接方式,若节点x被分为x1和x2,节点y被分为y1和y2。若x和y连接,则将x2连y1,y2连x1,残量都为最大值。

    然后跑一遍网络流就可以了。

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<cstdlib>
    #include<cmath>
    #include<algorithm>
    #include<queue>
    #include<stack>
    #include<ctime>
    #include<vector>
    #define inf (2e8)
    using namespace std;
    int n,m,l;
    struct node
    {
        int next,to,cap;
    }edge[200001];
    int head[100001],size=1,a[190001];
    void putin(int from,int to,int cap)
    {
        size++;
        edge[size].next=head[from];
        edge[size].to=to;
        edge[size].cap=cap;
        head[from]=size;
    }
    void in(int from,int to,int cap)
    {
        putin(from,to,cap);
        putin(to,from,0);
    }
    int dist[100001],numbs[100001];
    void bfs(int src,int des)
    {
        int i;
        queue<int>mem;
        mem.push(des);
        dist[des]=0;numbs[0]++;
        while(!mem.empty())
        {
            int x=mem.front();mem.pop();
            for(i=head[x];i!=-1;i=edge[i].next)
            {
                int y=edge[i].to;
                if(edge[i].cap==0&&dist[y]==0&&y!=des)
                {
                    dist[y]=dist[x]+1;
                    numbs[dist[y]]++;
                    mem.push(y);
                }
            }
        }
        return;
    }
    int dfs(int src,int flow,int des)
    {
        if(src==des)return flow;
        int i,low=0,mindist=n*2+2;
        for(i=head[src];i!=-1;i=edge[i].next)
        {
            int y=edge[i].to;
            if(edge[i].cap)
            {
                if(dist[y]==dist[src]-1)
                {
                    int t=dfs(y,min(flow-low,edge[i].cap),des);
                    edge[i].cap-=t;
                    edge[i^1].cap+=t;
                    low+=t;
                    if(dist[src]>=n*2+2)return low;
                    if(low==flow)break;
                }
                mindist=min(mindist,dist[y]+1);
            }
        }
        if(!low)
        {
            if(!(--numbs[dist[src]]))dist[0]=n*2+2;
            ++numbs[dist[src]=mindist];
        }
        return low;
    }
    int ISAP(int src,int des)
    {
        int ans=0;
        bfs(src,des);
        while(dist[0]<n*2+2)ans+=dfs(src,2e8,des);
        return ans;
    }
    int main()
    {
        int i,j;
        memset(head,-1,sizeof(head));
        scanf("%d%d%d",&n,&m,&l);
        for(i=1;i<=m;i++)
        {
            int from,to;
            scanf("%d%d",&from,&to);
            in(n+from,to,inf);
            in(n+to,from,inf);
        }
        for(i=1;i<=l;i++){scanf("%d",&j);a[j]=1;}
        in(1,n+1,inf);
        for(i=2;i<=n;i++)
        {
            if(a[i]==1){in(i,n+i,inf);in(n+i,2*n+1,inf);}
            else in(i,n+i,1);
        }
        in(0,1,inf);
        int maxflow=ISAP(0,n*2+1);
        cout<<maxflow;
        return 0;
    }
  • 相关阅读:
    Qt 4.x调试器问题,缺失调试助手。
    Qt 如何判断文件是不是一个目录
    Qt 5.7设置调试器
    Qt 无法解析外部文件2001,2019之类的
    TCP/UDP socket
    Qt 5.7 版本+2013VS环境配置
    骑行、318总结心得啊经验什么的
    蓝牙硬件交互数据传输Demo
    iOS蓝牙开发总结-4
    iOS蓝牙传输数据演示-3
  • 原文地址:https://www.cnblogs.com/huangdalaofighting/p/6915555.html
Copyright © 2020-2023  润新知