POJ1149 PIGS

luogu:嘟嘟嘟

poj:嘟嘟嘟

这是一道简化模型好题,这篇论文讲的太好了:网络流建模汇总,感觉我已经无需多讲。

但我这个代码没有合并相同边的容量,不过节点数是最少的。

  1 #include<cstdio>
  2 #include<iostream>
  3 #include<cmath>
  4 #include<algorithm>
  5 #include<cstring>
  6 #include<cstdlib>
  7 #include<cctype>
  8 #include<vector>
  9 #include<stack>
 10 #include<queue>
 11 using namespace std;
 12 #define enter puts("") 
 13 #define space putchar(' ')
 14 #define Mem(a, x) memset(a, x, sizeof(a))
 15 #define rg register
 16 typedef long long ll;
 17 typedef double db;
 18 const int INF = 0x3f3f3f3f;
 19 const db eps = 1e-8;
 20 const int maxe = 1e4 + 5;
 21 const int maxm = 1e3  + 5;
 22 const int maxn = 105;
 23 inline ll read()
 24 {
 25   ll ans = 0;
 26   char ch = getchar(), last = ' ';
 27   while(!isdigit(ch)) {last = ch; ch = getchar();}
 28   while(isdigit(ch)) {ans = ans * 10 + ch - '0'; ch = getchar();}
 29   if(last == '-') ans = -ans;
 30   return ans;
 31 }
 32 inline void write(ll x)
 33 {
 34   if(x < 0) x = -x, putchar('-');
 35   if(x >= 10) write(x / 10);
 36   putchar(x % 10 + '0');
 37 }
 38 
 39 int n, m, t;
 40 int a[maxm], pre[maxm];
 41 
 42 struct Edge
 43 {
 44   int nxt, from, to, cap, flow;
 45 }e[maxe];
 46 int head[maxn], ecnt = 1;
 47 void addEdge(int x, int y, int w)
 48 {
 49   e[++ecnt] = (Edge){head[x], x, y, w, 0};
 50   head[x] = ecnt;
 51   e[++ecnt] = (Edge){head[y], y, x, 0, 0};
 52   head[y] = ecnt;
 53 }
 54 
 55 int dis[maxn];
 56 bool bfs()
 57 {
 58   Mem(dis, 0); dis[0] = 1;
 59   queue<int> q; q.push(0);
 60   while(!q.empty())
 61     {
 62       int now = q.front(); q.pop();
 63       for(int i = head[now]; i; i = e[i].nxt)
 64     {
 65       if(!dis[e[i].to] && e[i].cap > e[i].flow)
 66         {
 67           dis[e[i].to] = dis[now] + 1;
 68           q.push(e[i].to);
 69         }
 70     }
 71     }
 72   return dis[t];
 73 }
 74 int cur[maxn];
 75 int dfs(int now, int res)
 76 {
 77   if(now == t || res == 0) return res;
 78   int flow = 0, f;
 79   if(!cur[now]) cur[now] = head[now];
 80   for(int &i = cur[now]; i; i = e[i].nxt)
 81     {
 82       if(dis[e[i].to] == dis[now] + 1 && (f = dfs(e[i].to, min(res, e[i].cap - e[i].flow))) > 0)
 83     {
 84       e[i].flow += f; e[i ^ 1].flow -= f;
 85       flow += f; res -= f;
 86       if(res == 0) break;
 87     }
 88     }
 89   return flow;
 90 }
 91 
 92 int maxflow()
 93 {
 94   int flow = 0;
 95   while(bfs())
 96     {
 97       Mem(cur, 0);
 98       flow += dfs(0, INF);
 99     }
100   return flow;
101 }
102 
103 
104 int main()
105 {
106   m = read(); n = read(); t = n + 1;
107   for(int i = 1; i <= m; ++i) a[i] = read();
108   for(int i = 1; i <= n; ++i)
109     {
110       int k = read();
111       for(int j = 1; j <= k; ++j)
112     {
113       int x = read();
114       if(!pre[x]) addEdge(0, i, a[x]);
115       else addEdge(pre[x], i, INF);
116       pre[x] = i;
117     }
118       int w = read();
119       addEdge(i, t, w);
120     }
121   write(maxflow()), enter;
122   return 0;
123 }
View Code

猜你喜欢

转载自www.cnblogs.com/mrclr/p/9814363.html
今日推荐