hdu 3061 Battle 最大权闭合图

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3061

由于小白同学近期习武十分刻苦,很快被晋升为天策军的统帅。而他上任的第一天,就面对了一场极其困难的战斗:
据侦查兵回报,前方共有N座城池,考虑到地势原因,最终得到一个结论:攻占某些城池之前必须攻占另外一些城池。
事实上,可以把地图看做是一张拓扑图,而攻占某个城池,就意味着必须先攻占它的所有前驱结点。
小白还做了一份调查,得到了攻占每个城池会对他的兵力产生多少消耗(当然也可能会得到增长,因为每攻占一个城池,便可以整顿军队,扩充兵力,天策军的兵力十分庞大,如果不考虑收益,他们可以攻取所有的城池)。
现在请你帮小白统帅做一份战斗计划,挑选攻打哪些城市,使得天策军在战斗过后军容最为壮大。
 
题意描述:如题所示。
算法分析:最大权闭合图的水题。
  1 #include<iostream>

  2 #include<cstdio>

  3 #include<cstring>

  4 #include<cstdlib>

  5 #include<cmath>

  6 #include<algorithm>

  7 #include<queue>

  8 #define inf 0x7fffffff

  9 using namespace std;

 10 const int maxn=500+10;

 11 const int M = 250000+10;

 12 

 13 int n,m,from,to;

 14 struct node

 15 {

 16     int v,flow;

 17     int next;

 18 }edge[M*3];

 19 int head[maxn],edgenum;

 20 

 21 void add(int u,int v,int flow)

 22 {

 23     edge[edgenum].v=v ;edge[edgenum].flow=flow ;

 24     edge[edgenum].next=head[u] ;head[u]=edgenum++ ;

 25 

 26     edge[edgenum].v=u ;edge[edgenum].flow=0 ;

 27     edge[edgenum].next=head[v] ;head[v]=edgenum++ ;

 28 }

 29 

 30 int d[maxn];

 31 int bfs()

 32 {

 33     memset(d,0,sizeof(d));

 34     d[from]=1;

 35     queue<int> Q;

 36     Q.push(from);

 37     while (!Q.empty())

 38     {

 39         int u=Q.front() ;Q.pop() ;

 40         for (int i=head[u] ;i!=-1 ;i=edge[i].next)

 41         {

 42             int v=edge[i].v;

 43             if (!d[v] && edge[i].flow)

 44             {

 45                 d[v]=d[u]+1;

 46                 Q.push(v);

 47                 if (v==to) return 1;

 48             }

 49         }

 50     }

 51     return 0;

 52 }

 53 

 54 int dfs(int u,int flow)

 55 {

 56     if (u==to || flow==0) return flow;

 57     int cap=flow;

 58     for (int i=head[u] ;i!=-1 ;i=edge[i].next)

 59     {

 60         int v=edge[i].v;

 61         if (d[v]==d[u]+1 && edge[i].flow)

 62         {

 63             int x=dfs(v,min(edge[i].flow,cap));

 64             edge[i].flow -= x;

 65             edge[i^1].flow += x;

 66             cap -= x;

 67             if (cap==0) return flow;

 68         }

 69     }

 70     return flow-cap;

 71 }

 72 

 73 int dinic()

 74 {

 75     int sum=0;

 76     while (bfs()) sum += dfs(from,inf);

 77     return sum;

 78 }

 79 

 80 int main()

 81 {

 82     while (scanf("%d%d",&n,&m)!=EOF)

 83     {

 84         int a,b;

 85         memset(head,-1,sizeof(head));

 86         edgenum=0;

 87         from=n+1;

 88         to=from+1;

 89         int sum=0;

 90         for (int i=1 ;i<=n ;i++)

 91         {

 92             scanf("%d",&a);

 93             if (a>0) {sum += a ;add(from,i,a);}

 94             else add(i,to,-a);

 95         }

 96         for (int i=0 ;i<m ;i++)

 97         {

 98             scanf("%d%d",&a,&b);

 99             add(a,b,inf);

100         }

101         printf("%d\n",sum-dinic());

102     }

103     return 0;

104 }

 

你可能感兴趣的:(bat)