最小费用最大流
有两个地方没搞懂 需要接下来研究一下 。。。
#include <iostream>
#include <stdio.h>
#include <string.h>
#include <algorithm>
#include <queue>
#include <stack>
#include <map>
#include <limits.h>
using namespace std;
const int inf=1e8-1;
const int eMax=4e4+5; //边数
const int nMax=10002; //顶点数
struct
{
int v, cap, cost, next, re; // re记录逆边的下标。
} edge[eMax];
int n, m, ans;
int k, edgeHead[nMax];
int que[nMax], pre[nMax], dis[nMax];
bool vis[nMax];
void add(int u, int v, int ca, int co)
{
edge[k].v = v;
edge[k].cap = ca;
edge[k].cost = co;
edge[k].next = edgeHead[u];
edge[k].re = k + 1;
edgeHead[u] = k ++;
edge[k].v = u;
edge[k].cap = 0;
edge[k].cost = -co;
edge[k].next = edgeHead[v];
edge[k].re = k - 1;
edgeHead[v] = k ++;
}
bool spfa() // 源点为0,汇点为n。
{
int i, head = 0, tail = 1;
for(i = 0; i <= n; i ++)
{
dis[i] = inf;
vis[i] = false;
}
dis[0] = 0;
que[0] = 0;
vis[0] = true;
while(tail > head) // 这里最好用队列,有广搜的意思,堆栈像深搜。
{
int u = que[head ++];
for(i = edgeHead[u]; i != 0; i = edge[i].next)
{
int v = edge[i].v;
if(edge[i].cap && dis[v] > dis[u] + edge[i].cost)
{
dis[v] = dis[u] + edge[i].cost;
pre[v] = i;
if(!vis[v])
{
vis[v] = true;
que[tail ++] = v;
}
}
}
vis[u] = false;
}
if(dis[n] == inf) return false;
return true;
}
void end()
{
int u, p, sum = inf;
for(u = n; u != 0; u = edge[edge[p].re].v)
{
p = pre[u];
sum = min(sum, edge[p].cap);
}
for(u = n; u != 0; u = edge[edge[p].re].v)
{
p = pre[u];
edge[p].cap -= sum;
edge[edge[p].re].cap += sum;
ans += sum * edge[p].cost; // cost记录的为单位流量费用,必须得乘以流量。
}
}
int main()
{
while(~scanf("%d%d",&n,&m))
{
k=1;
for(int i=0; i<m; i++)
{
int a,b,c;
scanf("%d%d%d",&a,&b,&c);
add(a,b,1,c);
add(b,a,1,c); //不明白为什么要建两次边~~~
}
add(0,1,2,0);
n++;
add(n-1,n,2,0);
ans = 0;
while(spfa())
{
end();
}
printf("%d\n",ans); //ans为最小费用, 那最大流的结果怎么表示呢?
}
return 0;
}