最大权闭包模型中源点与正收益的点连边,负收益的点与汇点连边,容量取绝对值,然后相关联的点之间之间连容量为无穷大的边。

 具体可参见胡伯涛:《最小割模型在信息学竞赛中的应用》

 

HDU 3061 Battle

  应该是最裸的最大权闭包题了。

  1 #include <vector>
  2 #include <list>
  3 #include <map>
  4 #include <set>
  5 #include <queue>
  6 #include <deque>
  7 #include <stack>
  8 #include <algorithm>
  9 #include <sstream>
 10 #include <iostream>
 11 #include <iomanip>
 12 #include <cstdio>
 13 #include <cstdlib>
 14 #include <cstring>
 15 #include <cmath>
 16 #include <queue>
 17 using namespace std;
 18 #define pii         pair<LL,LL>
 19 #define    clr(a)      memset((a),0,sizeof (a))
 20 #define    rep(i,a,b)  for(LL i=(a);i<=(LL)(b);i++)
 21 #define    per(i,a,b)  for(LL i=(a);i>=(LL)(b);i--)
 22 #define oo          ((LL)2000000007)*((LL)2000000007)
 23 #define    eps         1e-6
 24 #define    MAXN        1005
 25 #define MAXM        200005
 26 #define MOD         1000000007
 27 #define debug       puts("reach here")
 28 #define MP          make_pair
 29 #define PB          push_back
 30 #define RI(x)       scanf("%I64d",&x)
 31 #define RII(x,y)    scanf("%I64d%I64d",&x,&y)
 32 #define RIII(x,y,z) scanf("%d%d%d",&x,&y,&z)
 33 typedef long long LL;
 34 
 35 struct Edge
 36 {
 37     int u, v, next;
 38     LL w;
 39 }E[MAXM];     
 40 
 41 int gap[MAXN], pre[MAXN], cur[MAXN], dis[MAXN];
 42 LL n, m;
 43 LL N;
 44 int head[MAXN], NE;
 45 bool vis[MAXN];
 46 
 47 void add_edge (int u, int v, LL w)
 48 {
 49     E[NE].u = u; E[NE].v = v; E[NE].w = w; E[NE].next = head[u]; head[u] = NE++;
 50     E[NE].u = v; E[NE].v = u; E[NE].w = 0; E[NE].next = head[v]; head[v] = NE++;
 51 }
 52 
 53 inline void checkmin(LL &a,LL b)  {if(a == -1 || a > b)a = b;}
 54 
 55 LL sap(int s, int t)
 56 {
 57     clr(dis); clr(gap);
 58     for(int i=0;i<N;++i) cur[i]=head[i];
 59     int u=pre[s]=s;
 60     LL maxflow=0;
 61     LL aug=-1;
 62     gap[0]=N;
 63     while(dis[s]<N)
 64     {
 65 loop:for(int &i=cur[u];i!=-1;i=E[i].next)
 66         {
 67             LL v=E[i].v;
 68             if(E[i].w && dis[u]==dis[v]+1)
 69             {
 70                 checkmin(aug,E[i].w);
 71                 pre[v]=u;
 72                 u=v;
 73                 if(v==t)
 74                 {
 75                     maxflow += aug;
 76                     for(u=pre[u];v!=s;v=u,u=pre[u])
 77                     {
 78                         E[cur[u]].w-=aug;
 79                         E[cur[u]^1].w+=aug;
 80                     }
 81                     aug=-1;
 82                 }
 83                 goto loop;
 84             }
 85         }
 86         int mindis=N;
 87         for(int i=head[u];i!=-1;i=E[i].next)
 88         {
 89             int v=E[i].v;
 90             if(E[i].w && mindis>dis[v])
 91             {
 92                 cur[u]=i;
 93                 mindis=dis[v];
 94             }
 95         }
 96         if((--gap[dis[u]])==0) break;
 97         gap[dis[u]=mindis+1]++;
 98         u=pre[u];
 99     }
100     return maxflow;
101 }
102 
103 void init()
104 {
105     NE = 0; 
106     memset(head, -1, sizeof head);
107 }
108 
109 int main()
110 {
111     int a, b;
112     LL sum, v;
113     while(RII(n, m) != EOF)
114     {
115         init();
116         LL s = 0, t = n + 1;
117         sum = 0;
118         N = t + 1;
119         rep(i,1,n)
120         {
121             RI(v);
122             if(v > 0)
123             {
124                 add_edge(s, i, v);
125                 sum += v;
126             }
127             else
128                 add_edge(i, t, -v);
129         }
130         rep(i,1,m)
131         {
132             scanf("%d%d", &a, &b);
133             add_edge(a, b, oo);
134         }
135        printf("%I64d\n", sum - sap(s, t));
136     }
137     return 0;
138 }
View Code

相关文章:

  • 2022-12-23
  • 2021-07-16
  • 2022-12-23
  • 2021-12-23
  • 2022-01-01
  • 2021-12-23
猜你喜欢
  • 2022-12-23
  • 2022-12-23
  • 2022-12-23
  • 2022-12-23
  • 2021-09-09
  • 2021-08-05
  • 2022-12-23
相关资源
相似解决方案