bzoj 1585: [Usaco2009 Mar]Earthquake Damage 2 地震伤害 最小割

来源:互联网 发布:2016年7月淘宝新政策 编辑:程序博客网 时间:2024/05/24 05:16

题意

Farmer John的农场里有P个牧场,有C条无向道路连接着他们,第i条道路连接着两个牧场Ai和Bi,注意可能有很多条道路连接着相同的Ai和Bi,并且Ai有可能和Bi相等。Farmer John在1号牧场里。由于地震,某些牧场被损坏,但由于信春哥,C条道路没有一条损坏。有N头奶牛,他们在不同的牧场里,于是N <= P。他们一一向Farmer John报告。第i头奶牛报告给Farmer John一个整数Report_i,代表第Report_i个牧场没有损毁,但不能够从第Report_i个牧场经过一些没有损坏的牧场到达1号牧场。现在Farmer John想知道,最少有多少损坏的牧场。
1 <= P <=3000
1 <= C <=20000

分析

把1设为原点,把所有Report向汇点连边,其余点拆点,最小割即是答案。

mdzz读入的时候把m达成了n,害得我调了一晚上2333

代码

#include<iostream>#include<cstdio>#include<cstdlib>#include<cstring>#include<algorithm>#include<queue>using namespace std;const int N=6005;const int inf=1e9;int n,m,c,cnt,last[N],dis[N],cur[N],ans,vis[N],s,t;struct edge{int to,c,next;}e[N*30];queue<int> q;void addedge(int u,int v,int c){    e[++cnt].to=v;e[cnt].c=c;e[cnt].next=last[u];last[u]=cnt;    e[++cnt].to=u;e[cnt].c=0;e[cnt].next=last[v];last[v]=cnt;}bool bfs(){    for (int i=s;i<=t;i++) dis[i]=0;    while (!q.empty()) q.pop();    dis[s]=1;q.push(s);    while (!q.empty())    {        int u=q.front();q.pop();        for (int i=last[u];i;i=e[i].next)            if (e[i].c&&!dis[e[i].to])            {                dis[e[i].to]=dis[u]+1;                if (e[i].to==t) return 1;                q.push(e[i].to);            }    }    return 0;}int dfs(int x,int maxf){    if (x==t||!maxf) return maxf;    int ret=0;    for (int &i=cur[x];i;i=e[i].next)        if (e[i].c&&dis[e[i].to]==dis[x]+1)        {            int f=dfs(e[i].to,min(e[i].c,maxf-ret));            e[i].c-=f;            e[i^1].c+=f;            ret+=f;            if (maxf==ret) break;        }    return ret;}void dinic(){    while (bfs())    {        for (int i=s;i<=t;i++) cur[i]=last[i];        ans+=dfs(s,inf);    }}int main(){    scanf("%d%d%d",&n,&m,&c);    cnt=1;    for (int i=1;i<=m;i++)    {        int x,y;        scanf("%d%d",&x,&y);        addedge(x+n,y,inf);        addedge(y+n,x,inf);    }    s=0;t=n*2+1;    addedge(s,1,inf);    for (int i=1;i<=c;i++)    {        int x;        scanf("%d",&x);        vis[x]=1;        addedge(x+n,t,inf);    }    vis[1]=1;    for (int i=1;i<=n;i++)        if (!vis[i]) addedge(i,i+n,1);        else addedge(i,i+n,inf);    dinic();    printf("%d",ans);    return 0;}
原创粉丝点击