100 #P1121. *【最小费用流】游农场[Farm Tour, USACO03Feb]

*【最小费用流】游农场[Farm Tour, USACO03Feb]

Description

【题意】
约翰家有 $N$ 间牛棚,M条双向道路连接了这些牛棚,第 $i$ 条道路连接了第 $A_i$ 间牛棚和第 $B_i$ 间牛棚,长度为 $L_i$ 。
所有牛棚中最好的是第一间和最后一间,所以当有朋友来访时,他会带着朋友从第一间牛棚走到第 $N$ 间牛棚,然后再回到第一间牛棚。
约翰想让朋友多看看乡村不同的景色,所以希望来回的路上不重复经过任何一条道路,不过重复经过一间牛棚是允许的。
请帮助约翰选择一条路线,使得往返路径的总长度最短。输入数据保证路线总是存在的。

【输入格式】
第一行:两个整数 $N$ 和 $M$,$1 \le N \le 1000,1 \le M \le 10000$
第二行到第 $M+1$ 行:第 $i+1$ 行有三个整数 $A_i$,$B_i$ 和 $L_i$ ,$1 \le A_i,B_i \le N$,$1 \le L_i \le 35000$

【输出格式】
单个整数,表示最短路线的总长度。

【样例输入】
4 5
1 2 1
2 3 1
3 4 1
1 3 2
2 4 2

【样例输出】
6

【解释】
1→2→4→3→1

Hint

#include<bits/stdc++.h>
using namespace std;
const int N=1100,M=50000;
struct edge{int x,y,f,c,pre;}a[M];int alen,last[N],cur[N];
void ins(int x,int y,int f,int c)
{
    a[++alen]={x,y,f,c,last[x]};last[x]=alen;
    a[++alen]={y,x,0,-c,last[y]};last[y]=alen;
}
int n,m,st,ed,d[N];bool v[N];
bool spfa()
{
    queue<int> q;
    memset(d,0x0f,sizeof(d));d[st]=0;
    memset(v,0,sizeof(v));
    q.push(st);v[st]=1;
    while(!q.empty())
	{
        int x=q.front();q.pop();v[x]=0;
        for(int k=last[x];k;k=a[k].pre)if(a[k].f)
		{
            int y=a[k].y;
            if(d[y]>d[x]+a[k].c)
			{
                d[y]=d[x]+a[k].c;
                if(!v[y])q.push(y),v[y]=1;
            }
        }    
    }
    return d[ed]!=d[0];
}
int ans;
int dinic(int x,int f)
{
    if(x==ed) return ans+=d[ed]*f,f;
    int sx=0;
    v[x]=1;
    for(int k=cur[x];k;k=a[k].pre)if(a[k].f)
	{
        cur[x]=k;
        int y=a[k].y;if(v[y])continue;
        if(d[y]==a[k].c+d[x])
		{
            int sy=dinic(y,min(f-sx,a[k].f));
            a[k].f-=sy,a[k^1].f+=sy;
            sx+=sy;if(sx==f) return f;
        }
    }
    if(sx>0)v[x]=0;
    return sx;
}

int main() { scanf("%d%d",&n,&m); alen=1;memset(last,0,sizeof(last)); for(int i=1;i<=m;i++) { int x,y,c,f;scanf("%d%d%d",&x,&y,&c); ins(x,y,1,c);ins(y,x,1,c); } st=n+1,ed=n+2; ins(st,1,2,0); ins(n,ed,2,0); ans=0; while(spfa()) { memcpy(cur,last,sizeof(cur)); int t=dinic(st,1<<30); } printf("%d\n",ans); return 0; }

</p>