题目链接:http://hdu.hustoj.com/showproblem.php?pid=6118
掉坑里了,图很好建,Wa了一发,看了Disscuss里面有人提供了一组样例,画图发现:最小流模板是在满足最大流情况下的最小费用,而本题目不需要满足最大流直接求最小费用。注意一下。
/*
5 4
1 2 1 2
2 1 2 1
2 3 4 5
5 4 3 2
100 1 1 1
1 2 1
2 3 1
3 4 1
1 5 1
*/
应该输出8的。
#include <iostream> #include <cstdio> #include <cstring> #include <vector> #include <queue> #include <algorithm> using namespace std; const int maxn = 4e3; const int INF = 1e9; int dist[maxn]; int tot,head[maxn]; int pv[maxn],pe[maxn]; struct edge { int to,pre,cap,cost; }e[20000]; typedef pair<int,int> P; void init() { tot = 0; memset(head,-1,sizeof(head)); } void add(int from,int to,int cap,int cost) { e[tot].pre = head[from]; e[tot].to = to; e[tot].cap = cap; e[tot].cost = cost; head[from] = tot++; } void addedge(int from,int to,int cap,int cost) { add(from,to,cap,cost); add(to,from,0,-cost); } int ans = 10000000; int min_cost_flow(int s,int t,int f,int& max_flow) { int ret = 0; while(f>0) { priority_queue<P,vector<P>,greater<P> >q; for(int i=0;i<maxn;i++) dist[i] = INF; dist[s] = 0; q.push(P(0,s)); while(!q.empty()) { P cur = q.top(); q.pop(); int v = cur.second; if(dist[v]<cur.first) continue; for(int i=head[v];i>=0;i=e[i].pre) { int to = e[i].to,cap = e[i].cap,cost = e[i].cost; if(cap>0&&dist[to]>dist[v]+cost) { pv[to] = v,pe[to] = i; dist[to] = dist[v] + cost; q.push(P(dist[to],to)); } } } if(dist[t]==INF) return ret; ///当所有边的流量都流净后,即没有残余网络,返回。 int d = f; for(int v=t;v!=s;v=pv[v]) { d = min(d,e[pe[v]].cap); } f -= d; max_flow += d; ans = min(ans,ret); ret += d*dist[t]; ///走一单位就消耗dist[t] for(int v=t;v!=s;v=pv[v]) { e[pe[v]].cap -= d; e[pe[v]^1].cap += d; } } return ret; } int a[maxn],b[maxn],c[maxn],d[maxn]; int main() { int n,m; while(scanf("%d %d",&n,&m)!=EOF) { int s=0,t=3500; init(); //别忘写 for(int i=1;i<=n;i++) { scanf("%d %d %d %d",&a[i],&b[i],&c[i],&d[i]); } for(int i=1;i<=n;i++) { addedge(s,i,b[i],a[i]); addedge(i,t,d[i],-c[i]); } for(int i=1;i<=m;i++) { int u,v,k; scanf("%d %d %d",&u,&v,&k); addedge(u,v,INF,k); addedge(v,u,INF,k); } int maxflow = 0; ans = 10000000; min_cost_flow(s,t,INF,maxflow); if(ans>=0) printf("0 "); else printf("%d ",-ans); } return 0; } /* 5 4 1 2 1 2 2 1 2 1 2 3 4 5 5 4 3 2 100 1 1 1 1 2 1 2 3 1 3 4 1 1 5 1 */