- 題目鏈接:http://poj.org/problem?id=2135
- 題意:給你一個無向圖,要找出從1號點 到 N號點 的兩條不相干的路徑的最小總長。
- 思路:用一個超級源點,連向1號點,長度爲0,容量爲2。再將N號點連向一個超級匯點,長度爲0,容量爲2(兩條路徑)。其他邊的話按照原圖裏的建雙向邊,cost就是其邊長,容量爲1(路徑之間不相干)。然後直接算最小費用最大流就行了。
#include <cstdio>
#include <iostream>
#include <algorithm>
#include <cstring>
#include <vector>
#include <queue>
#include <stack>
#include <set>
#include <map>
#include <math.h>
#define pi acos(-1)
#define fastio ios_base::sync_with_stdio(false);cin.tie(0);cout.tie(0);
using namespace std;
typedef long long LL;
typedef pair<int, int> PII;
typedef pair<LL, LL> PLL;
const int INF = 0x3f3f3f3f;
const LL ll_INF = 0x3f3f3f3f3f3f3f3f;
const int maxn = 200 + 10;
const int Max_row = 110, Max_col = 110, Max_v = 110*3, Max_e = 110*110+110*3;
char Grid[Max_row][Max_col];
PII Vertex[Max_v];
int tot=0;
int tol;
int head[Max_e];
int st=0,en=0;
int dis[maxn*maxn];
int vis[maxn*maxn];
int pre[maxn*maxn];
struct Edge
{
int u;
int v;
int cap;
int cost;
int next;
}edge[maxn*maxn + maxn*3];
void init()
{
memset(head,-1,sizeof(head));
tol=0;
tot=0;
}
void add_edge(int u,int v,int cap,int cost)
{
edge[tol].u=u;edge[tol].v=v;edge[tol].cap=cap;
edge[tol].cost=cost;edge[tol].next=head[u];
head[u]=tol++;
edge[tol].u=v;edge[tol].v=u;edge[tol].cap=0;
edge[tol].cost=-cost;edge[tol].next=head[v];
head[v]=tol++;
}
bool spfa(int s,int t ,int n)
{
for(int i=0;i<=n;i++)
{
dis[i]=INF;
vis[i]=0;
pre[i]=-1;
}
dis[s]=0;
vis[s]=1;
queue<int> Q;
Q.push(s);
while(!Q.empty())
{
int u=Q.front();
Q.pop();
vis[u]=0;
for(int k=head[u];k!=-1;k=edge[k].next)
{
int v=edge[k].v;
int cost=edge[k].cost;
if(edge[k].cap && dis[v]> dis[u]+cost)
{
dis[v]=dis[u]+cost;
pre[v]=k;
if(!vis[v])
{
vis[v]=1;
Q.push(v);
}
}
}
}
if(dis[t]==INF)return 0;
return 1;
}
int MCMF(int s,int t,int n)
{
int minflow;
int mincost=0;
while(spfa(s,t,n))
{
minflow=INF;
for(int k=pre[t];k!=-1;k=pre[edge[k].u])
{
minflow=min(minflow,edge[k].cap);
}
for(int k=pre[t];k!=-1;k=pre[edge[k].u])
{
edge[k].cap-=minflow;
edge[k^1].cap+=minflow;
}
mincost+=dis[t];
}
return mincost;
}
int main()
{
init();
int N, M;
scanf("%d%d", &N, &M);
st = 0;
en = N + 1;
for(int i=1; i<=M; i++){
int u, v, cost;
scanf("%d%d%d", &u, &v, &cost);
add_edge(u, v, 1, cost);
add_edge(v, u, 1, cost);
}
add_edge(st, 1, 2, 0);
add_edge(N, en, 2, 0);
printf("%d\n", MCMF(st, en, en));
}