/** * Deon Nicholas' solution to Water. * * The problem boils down to Max Flow. The interesting * part is the fact that we must "re-compute" the value * after updating (or inserting) a new edge. * * I use Dinic's algorithm for max flow. After a new edge, * we simply run one more pass of bfs/dfs (finding a maximal * set of shortest augmenting paths), and record the total change. * * This is correct since, after doing this, * we will have no more augmenting paths (and Ford/Fulkerson taught * us that a flow is maximum if and only if there are no more augmenting * paths). * * It is fast because you can prove (I think) that, if only a single * edge changes, then you will need at most one iteration of bfs/dfs * to find the new max flow (O(E) time). * * Thus the entire algorithm is O(sqrt(V)*E) for the initial max-flow * (this is the running time of Dinic's algorithm), plus O(E*K) * (where O(E) is the time taken per update, and K is the number of updates). * * This is sufficient. */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include using namespace std; #define FORALL(i,a,b) for(int i=(a);i<=(b);++i) #define FOR(i,n) for(int i=0;i<(n);++i) #define FORB(i,a,b) for(int i=(a);i>=(b);--i) typedef long long ll; typedef long double ld; typedef complex vec; typedef pair plli; typedef pair pii; typedef map mii; #define pb push_back #define mp make_pair #define INF 1000000000 #define zero 0 #define MAXNODE 105 typedef int num; struct edge { int b; num cap, f; int rev_id; }; vector E[MAXNODE]; int vis[MAXNODE], depth[MAXNODE]; bool bfs_aug(int s, int t, int p) { queue Q; Q.push(s); vis[s] = p; depth[s] = 0; int i,j,numE; while(!Q.empty()) { i = Q.front(); Q.pop(); if (i==t) return true; numE = E[i].size(); FOR(x,numE) if (j=E[i][x].b, vis[j]

E[i][x].f) vis[j] = p, depth[j] = depth[i]+1, Q.push(j); } return false; } num dfs_aug(int i, int t, num res, int p) { if (i==t) return res; int numE = E[i].size(); num sum=zero, v=zero; FOR(x,numE) { int j = E[i][x].b, r = E[i][x].rev_id; num c = min(E[i][x].cap - E[i][x].f,res); if (vis[j] == p) continue; if (c>zero && depth[j]==depth[i]+1 && (v=dfs_aug(j,t,c,p)) > zero) E[i][x].f += v, E[j][r].f -= v, res -= v, sum += v; } assert(res >= zero); if (res > 0) vis[i] = p; // didn't use all the residual? never come here again return sum; } num dinics(int s, int t, int& phase) { num ans = zero; for(++phase; bfs_aug(s,t,phase++)>0;) ans += dfs_aug(s,t,INF,phase++); return ans; } int adj[MAXNODE][MAXNODE]; // optimization: avoid duplicating edges void add_edge(int a, int b, num c, bool assert_unique) { if (adj[a][b] >= 0) { assert(!assert_unique || E[a][adj[a][b]].cap == 0); // sanity check E[a][adj[a][b]].cap += c; } else { edge x = {b,c,zero,(int)E[b].size()}; edge y = {a,zero,zero,(int)E[a].size()}; E[a].pb(x); E[b].pb(y); adj[a][b] = E[a].size() - 1; adj[b][a] = E[b].size() - 1; } } int main() { FOR(i,MAXNODE) FOR(j,MAXNODE) adj[i][j] = -1; int N,M,K,a,b,c; scanf("%d%d%d",&N,&M,&K); assert(N >= 2 && N <= 100); assert(0 <= M && M <= N*(N-1)/2); assert(1 <= K && K <= 10000); FOR(x,M) { scanf("%d%d%d",&a,&b,&c); assert(1<=a&&a