1.题面
http://poj.org/problem?id=1459
2.题意
水题
3.思路
看题意描述以为要拆点,但最后的求解出乎意料的简单
4.代码
/***************************************************************** > File Name: cpp_acm.cpp > Author: Uncle_Sugar > Mail: [email protected] > Created Time: Sat 01 Oct 2016 22:52:30 CST *****************************************************************/ # include <cstdio> # include <cstring> # include <cctype> # include <cmath> # include <cstdlib> # include <climits> # include <iostream> # include <iomanip> # include <set> # include <map> # include <vector> # include <stack> # include <queue> # include <algorithm> using namespace std; # define rep(i,a,b) for (i=a;i<=b;i++) # define rrep(i,a,b) for (i=b;i>=a;i--) struct QuickIO{ QuickIO(){const int SZ = 1<<20; setvbuf(stdin ,new char[SZ],_IOFBF,SZ); setvbuf(stdout,new char[SZ],_IOFBF,SZ); } //*From programcaicai*// }QIO; template<class T>void PrintArray(T* first,T* last,char delim=' '){ for (;first!=last;first++) cout << *first << (first+1==last?'\n':delim); } /* 1.see the size of the input data before you select your algorithm 2.cin&cout is not recommended in ACM/ICPC 3.pay attention to the size you defined, for instance the size of edge is double the size of vertex */ const int debug = 1; //# const int size = 10 + ; const int INF = INT_MAX>>1; typedef long long ll; const int MAXN = 5000 + 10; const int MAXM = MAXN*MAXN; struct Edge{ int to, f, nxt; }edge[MAXM]; int tot = 0; int head[MAXN]; void init(){ tot = 0; memset(head, -1, sizeof(head)); } void addedge(int from, int to, int f){ edge[tot].to = to;edge[tot].f = f; edge[tot].nxt = head[from]; head[from] = tot++; edge[tot].to = from;edge[tot].f = 0; edge[tot].nxt = head[to]; head[to] = tot++; } int level[MAXN]; bool bfs(int s, int t){ static queue<int> que; while (!que.empty()) que.pop(); memset(level, 0, sizeof(level)); que.push(s); level[s] = 1; while (!que.empty()){ int cur = que.front(); que.pop(); if (cur == t) return true; for (int e = head[cur]; ~e; e = edge[e].nxt){ int to = edge[e].to, f = edge[e].f; if (!level[to] && f){ level[to] = level[cur] + 1; que.push(to); } } } return false; } int dfs(int u, int t, int sup){ if (u == t) return sup; int ret = 0; for (int e = head[u]; ~e; e = edge[e].nxt){ int cur = edge[e].to, f = edge[e].f; if (level[cur] == level[u] + 1 && f){ int mi = min(sup - ret, f); int tf = dfs(cur, t, mi); edge[e].f -= tf; edge[e^1].f += tf; ret += tf; if (ret == sup) return ret; } } return ret; } int Dinic(int s, int t){ int ret = 0; while (bfs(s, t)) ret += dfs(s, t, INF); return ret; } int main() { /*std::ios::sync_with_stdio(false);cin.tie(0);*/ int n, np, nc, m; while (~scanf("%d%d%d%d", &n, &np, &nc, &m)){ init(); while (m--){ int a, b, c; while (getchar() != '('); scanf("%d,%d)%d", &a, &b, &c); ++a;++b; addedge(a, b, c); } while (np--){ int a, b; while (getchar() != '('); scanf("%d)%d", &a, &b); ++a; addedge(0, a, b); } while (nc--){ int a, b; while (getchar() != '('); scanf("%d)%d", &a, &b); ++a; addedge(a, n+1, b); } ll ans = Dinic(0, n+1); printf("%lld\n", ans); } return 0; }
附上kuangbin的非递归dinic代码, 感谢kuangbin大神
地址是:点击打开链接
/* 最大流模板 dinic算法 */ #include<stdio.h> #include<string.h> #include<algorithm> #include<iostream> using namespace std; const int INF=0x3f3f3f3f; const int MAXN=150;//点数的最大值 const int MAXM=20500;//边数的最大值 struct Node { int from,to,next; int cap; }edge[MAXM]; int tol; int dep[MAXN];//dep为点的层次 int head[MAXN]; int n; void init() { tol=0; memset(head,-1,sizeof(head)); } void addedge(int u,int v,int w)//第一条变下标必须为偶数 { edge[tol].from=u; edge[tol].to=v; edge[tol].cap=w; edge[tol].next=head[u]; head[u]=tol++; edge[tol].from=v; edge[tol].to=u; edge[tol].cap=0; edge[tol].next=head[v]; head[v]=tol++; } int BFS(int start,int end) { int que[MAXN]; int front,rear; front=rear=0; memset(dep,-1,sizeof(dep)); que[rear++]=start; dep[start]=0; while(front!=rear) { int u=que[front++]; if(front==MAXN)front=0; for(int i=head[u];i!=-1;i=edge[i].next) { int v=edge[i].to; if(edge[i].cap>0&&dep[v]==-1) { dep[v]=dep[u]+1; que[rear++]=v; if(rear>=MAXN)rear=0; if(v==end)return 1; } } } return 0; } int dinic(int start,int end) { int res=0; int top; int stack[MAXN];//stack为栈,存储当前增广路 int cur[MAXN];//存储当前点的后继 while(BFS(start,end)) { memcpy(cur,head,sizeof(head)); int u=start; top=0; while(1) { if(u==end) { int min=INF; int loc; for(int i=0;i<top;i++) if(min>edge[stack[i]].cap) { min=edge[stack[i]].cap; loc=i; } for(int i=0;i<top;i++) { edge[stack[i]].cap-=min; edge[stack[i]^1].cap+=min; } res+=min; top=loc; u=edge[stack[top]].from; } for(int i=cur[u];i!=-1;cur[u]=i=edge[i].next) if(edge[i].cap!=0&&dep[u]+1==dep[edge[i].to]) break; if(cur[u]!=-1) { stack[top++]=cur[u]; u=edge[cur[u]].to; } else { if(top==0)break; dep[u]=-1; u=edge[stack[--top]].from; } } } return res; } int main()//多源多汇点,在前面加个源点,后面加个汇点,转成单源单汇点 { //freopen("in.txt","r",stdin); //freopen("out.txt","w",stdout); int start,end; int np,nc,m; int u,v,z; while(scanf("%d%d%d%d",&n,&np,&nc,&m)!=EOF) { init(); while(m--) { while(getchar()!='('); scanf("%d,%d)%d",&u,&v,&z); u++;v++; addedge(u,v,z); } while(np--) { while(getchar()!='('); scanf("%d)%d",&u,&z); u++; addedge(0,u,z); } while(nc--) { while(getchar()!='('); scanf("%d)%d",&u,&z); u++; addedge(u,n+1,z); } start=0; end=n+1; int ans=dinic(start,end); printf("%d\n",ans); } return 0; }