http://poj.org/problem?id=1459
题意略去,没什么坑。只是多源多汇,加上超级源点和汇点建图就行。
Dinic 235ms
#include <stdio.h> #include <string.h> #include <queue> #include <algorithm> using namespace std; const int INF = 0x3f3f3f3f; int n,m,np,nc; int map[110][110]; char str[20]; int s,t; int dis[210]; bool bfs() //建立层次图 { memset(dis,-1,sizeof(dis)); dis[s] = 0; queue <int> que; while(!que.empty()) que.pop(); que.push(s); while(!que.empty()) { int u = que.front(); que.pop(); for(int i = 0; i <= n+1; i++) { if(dis[i] == -1 && map[u][i]) { dis[i] = dis[u]+1; que.push(i); } } } if(dis[t] > 0) return true; return false; } int dfs(int s, int delta = INF) //寻找最小残量 { if(s == t || delta == 0) return delta; int ans; int ret = 0; for(int i = 0; i <= n+1; i++) { if(map[s][i] && dis[i] == dis[s]+1 && (ans = dfs(i,min(delta,map[s][i])) ) ) { map[s][i] -= ans; map[i][s] += ans; ret += ans; delta -= ans; } } return ret; } int main() { while(~scanf("%d %d %d %d",&n,&np,&nc,&m)) { memset(map,0,sizeof(map)); int u,v,w; s = n; t = n+1; while(m--) { scanf("%s",str); sscanf(str,"(%d,%d)%d",&u,&v,&w); map[u][v] = w; } while(np--) { scanf("%s",str); sscanf(str,"(%d)%d",&v,&w); map[n][v] = w; } while(nc--) { scanf("%s",str); sscanf(str,"(%d)%d",&u,&w); map[u][n+1] = w; } int ans = 0; while(bfs()) { ans += dfs(s); } printf("%d\n",ans); } return 0; }
#include <stdio.h> #include <string.h> #include <algorithm> #include <queue> using namespace std; const int INF = 0x3f3f3f3f; int n,np,nc,m,s,t; int map[110][110]; char str[20]; int a[110],pre[110],flow[110][110],mf; queue <int>que; void maxflow() { memset(flow,0,sizeof(flow)); mf = 0; while(1) { memset(a,0,sizeof(a)); while(!que.empty()) que.pop(); a[s] = INF; que.push(s); while(!que.empty()) { int u = que.front(); que.pop(); for(int v = 0; v <= n+1; v++) { if(!a[v] && map[u][v] > flow[u][v]) { pre[v] = u; que.push(v); if(a[u] < map[u][v]-flow[u][v]) a[v] = a[u]; else a[v] = map[u][v]-flow[u][v]; } } } if(a[t] == 0) break; for(int u = t; u != s; u = pre[u]) { flow[ pre[u] ][u] += a[t]; flow[u][ pre[u] ] -= a[t]; } mf += a[t]; } } int main() { while(~scanf("%d %d %d %d",&n,&np,&nc,&m)) { memset(map,0,sizeof(map)); int u,v,w; s = n; t = n+1; while(m--) { scanf("%s",str); sscanf(str,"(%d,%d)%d",&u,&v,&w); map[u][v] = w; } while(np--) { scanf("%s",str); sscanf(str,"(%d)%d",&v,&w); map[n][v] = w; } while(nc--) { scanf("%s",str); sscanf(str,"(%d)%d",&u,&w); map[u][n+1] = w; } maxflow(); printf("%d\n",mf); } return 0; }