POJ1149 PIGS
luogu:嘟嘟嘟
poj:嘟嘟嘟
这是一道简化模型好题,这篇论文讲的太好了:网络流建模汇总,感觉我已经无需多讲。
但我这个代码没有合并相同边的容量,不过节点数是最少的。
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
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 }