【BZOJ 1585】 [Usaco2009 Mar]Earthquake Damage 2 地震伤害 最小割

来源:互联网 发布:微盘外汇交易平台源码 编辑:程序博客网 时间:2024/05/21 06:52

然后由于是求最少破坏数,还是比较好想得最小割模型,首先1号节点最为汇点,然后确定源点,因为题目是要求我们将给出的节点和1号节点分开,也就是要求出一条最小割将给出的点和1号节点隔开就好了,所以建立一个源点和所有给出的点连边容量为INF保证它不会被割掉就好了,然后拆点,给出的点一定是可行的所以边权为INF其他的为1,特别注意1号节点边权也是INF或者直接令1的入点为汇点,没了。

#include<cstdio>#include<cstring>#include<iostream>#define Q(a) (a+p)#define maxn 500020using namespace std;int q[maxn],s,t,p,c,n,last[maxn],head[maxn],tot,h[maxn];bool vvis[maxn];struct edge{int v,next,w;}e[maxn];void adde(int a,int b,int c){e[tot].v=b,e[tot].next=head[a],e[tot].w=c;head[a]=tot++;e[tot].v=a,e[tot].next=head[b],e[tot].w=0;head[b]=tot++;}bool bfs(){int l=0,r=1;for(int i=s;i<=2*p;i++)h[i]=-1;q[l]=h[0]=0;while(l<r){int u=q[l++];for(int v,i=head[u];i!=-1;i=e[i].next){if(h[v=e[i].v]==-1&&e[i].w){h[v]=h[u]+1;q[r++]=v;}}}return h[t]!=-1;}int dfs(int u,int f){if(u==t)return f;int used=0,w;for(int v,i=last[u];i!=-1;i=e[i].next)if(e[i].w&&h[v=e[i].v]==h[u]+1){w=min(f-used,e[i].w);last[u]=i;w=dfs(v,w);e[i].w-=w,e[i^1].w+=w,used+=w;if(used==f)return f;}if(used==0)h[u]=-1;return used;}int dinic(){int ans=0;while(bfs()){for(int i=s;i<=2*p;i++)last[i]=head[i];ans+=dfs(s,1e9);}return ans;}int main(){scanf("%d%d%d",&p,&c,&n);t=Q(1);memset(head,-1,sizeof(head));for(int a,b,i=1;i<=c;i++){scanf("%d%d",&a,&b);adde(Q(a),b,1e9),adde(Q(b),a,1e9);}for(int a,i=1;i<=n;i++){scanf("%d",&a);vvis[a]=true;adde(s,a,1e9);}for(int i=1;i<=p;i++)if(i==1||vvis[i])adde(i,Q(i),1e9);else adde(i,Q(i),1);printf("%d",dinic());return 0;}


0 0
原创粉丝点击