hdu 3061 (最大权闭合图)

来源:互联网 发布:网络小手论坛手机版 编辑:程序博客网 时间:2024/05/04 20:10

分析:城池之间有依赖关系,汇点与能获得兵力的城池连接,容量为可以获得的兵力,损耗兵力的城池与汇点连接容量为损耗的兵力,有依赖关系的城池间连边,容量为无穷大,跑网络流求出的最小割就是损耗的最小兵力,,,






#include<stdio.h>#include<string.h>const int N=510;const int inf=0x3fffffff;int dis[N],gap[N],start,end,ans,head[N],num;struct edge{int st,ed,flow,next;}e[N*N];void addedge(int x,int y,int w){e[num].st=x;e[num].ed=y;e[num].flow=w;e[num].next=head[x];head[x]=num++;e[num].st=y;e[num].ed=x;e[num].flow=0;e[num].next=head[y];head[y]=num++;}int dfs(int u,int minflow)  {      if(u==end)return minflow;      int i,v,f,min_dis=ans-1,flow=0;      for(i=head[u];i!=-1;i=e[i].next)      {          v=e[i].ed;          if(e[i].flow<=0)continue;          if(dis[v]+1==dis[u])          {              f=dfs(v,e[i].flow>minflow-flow?minflow-flow:e[i].flow);              e[i].flow-=f;              e[i^1].flow+=f;              flow+=f;              if(flow==minflow)break;              if(dis[start]>=ans)return flow;          }          min_dis=min_dis>dis[v]?dis[v]:min_dis;      }      if(flow==0)      {          if(--gap[dis[u]]==0)              dis[start]=ans;          dis[u]=min_dis+1;          gap[dis[u]]++;      }      return flow;  }int isap()  {      int maxflow=0;      memset(gap,0,sizeof(gap));      memset(dis,0,sizeof(dis));      gap[0]=ans;      while(dis[start]<ans)          maxflow+=dfs(start,inf);  //printf("%d\n",maxflow);    return maxflow;  }int main(){int i,x,y,n,m,k;while(scanf("%d%d",&n,&m)!=-1){memset(head,-1,sizeof(head));num=0;start=0;end=n+1;ans=end+1;k=0;for(i=1;i<=n;i++){scanf("%d",&x);if(x>=0){   addedge(start,i,x);   k+=x;}else addedge(i,end,-x);}for(i=1;i<=m;i++){scanf("%d%d",&x,&y);addedge(x,y,inf);}printf("%d\n",k-isap());}return 0;}