有N的点,1是farmer john的家 n是barn要求从1开始走到n再走回来,不许走重复的路线,使之能从1走到n在走回来,且要经过每个点。费用流的模型。
建立一个新源点容量为2,费用为0连向点1,然后n连向一个汇点,原来的图是无向图,所以要加2个有向边求解。之后就是费用流了
题目保证可以走回来的,这样加边的原因是有向边是在网络中有一定的关系的,有流量从A到B的流过,那么在最终的网络流中一定不可能从B到A流回来
#include <iostream>
#include <cstring>
#include <cstdio>
#include <queue>
#include <algorithm>
using namespace std;
class mincost
{
private:
const static int V = 1001;
const static int E = 1000001;
const static int INF = 0x7ffffff;
struct Edge
{
int v, cap, cost;
Edge *next;
} pool[E], *g[V], *pp, *pree[V];
int T, S, dis[V], pre[V];
int n, m;
void SPFA();
inline void addedge(int i, int j, int cap, int cost);
public:
bool initialize();
void mincost_maxflow();
};
void mincost::mincost_maxflow()
{
int flow = 0;
while (true)
{
SPFA();
if (dis[T] == INF)
break;
int minn = INF;
for (int i = T; i != S; i = pre[i])
minn = min(minn, pree[i]->cap);
for (int i = T; i != S; i = pre[i])
{
pree[i]->cap -= minn;
pool[(pree[i] - pool)^0x1].cap += minn;
flow += minn * pree[i]->cost;
}
}
printf("%d\n", flow);
}
void mincost::SPFA()
{
bool vst[V] = {false};
int cirq[V];
int tail = 0, u;
fill(dis, dis + T + 1, 0x7ffffff);
cirq[0] = S;
vst[S] = 1;
dis[S] = 0;
for (int j = 0; j <= tail; j++)
{
int v = cirq[j % n];
for (Edge *i = g[v]; i != NULL; i = i->next)
{
if (!i->cap)
continue;
u = i->v;
if (i->cost + dis[v] < dis[u])
{
dis[u] = i->cost + dis[v];
pree[u] = i;
pre[u] = v;
if (!vst[u])
{
tail++;
cirq[tail % n] = u;
vst[u] = true;
}
}
}
vst[v] = false;
}
}
void mincost::addedge(int i, int j, int cap, int cost)
{
pp->cap = cap;
pp->v = j;
pp->cost = cost;
pp->next = g[i];
g[i] = pp++;
}
bool mincost::initialize()
{
if (scanf("%d %d", &n, &m) != 2)
return false;
memset(g, 0, sizeof (g));
pp = pool;
S = 0, T = n + 1;
int v, u, c;
addedge(S, 1, 2, 0);
addedge(1, S, 0, 0);
addedge(n, T, 2, 0);
addedge(T, n, 0, 0);
n += 2;
for (int i = 0; i < m; i++)
{
scanf("%d %d %d", &v, &u, &c);
addedge(v, u, 1, c);
addedge(u, v, 0, -c);
addedge(u, v, 1, c);
addedge(v, u, 0, -c);
}
return true;
}
mincost g;
int main()
{
while (g.initialize())
g.mincost_maxflow();
return 0;
}