HDU 2135 最小费用流
http://poj.org/problem?id=2135
1 #include<iostream> 2 #include<cstdio> 3 #include<cstring> 4 #include<string> 5 #define nMAX 1002 6 #define mMAX 10005 7 #define inf 99999999 8 using namespace std; 9 int head[nMAX],qu[nMAX],dis[nMAX],pre[nMAX]; 10 bool vs[nMAX]; 11 int n,s_edge,ans; 12 struct Edge 13 { 14 int v,co,cap,nxt; 15 }edge[4*mMAX]; 16 void addedge(int u,int v,int cap,int co) 17 { 18 s_edge++; 19 edge[s_edge].v=v; 20 edge[s_edge].cap=cap; 21 edge[s_edge].co=co; 22 edge[s_edge].nxt=head[u]; 23 head[u]=s_edge; 24 25 s_edge++; 26 edge[s_edge].v=u; 27 edge[s_edge].cap=0; 28 edge[s_edge].co=-co; 29 edge[s_edge].nxt=head[v]; 30 head[v]=s_edge; 31 } 32 void spfa(int u) 33 { 34 int i,j,start,tail; 35 for(i=1;i<=n;i++) 36 { 37 dis[i]=inf; 38 vs[i]=0; 39 } 40 dis[u]=0; 41 vs[u]=1; 42 start=0, tail=1; 43 qu[start]=u; 44 while(start!=tail) 45 { 46 int t=qu[start++]; 47 for(int e=head[t];e;e=edge[e].nxt) 48 { 49 int v=edge[e].v; 50 if(edge[e].cap&&dis[v]>dis[t]+edge[e].co) 51 { 52 dis[v]=dis[t]+edge[e].co; 53 pre[v]=e; 54 if(!vs[v]) 55 { 56 vs[v]=1; 57 qu[tail++]=v; 58 if(tail==nMAX)tail=0; 59 } 60 } 61 } 62 vs[t]=0; 63 if(start==nMAX)start=0; 64 } 65 //if(dis[n]==inf)return 0; 66 //return 1; 67 } 68 void end(int s,int t) 69 { 70 int p,u; 71 for(u=t;u!=s;u=edge[p^1].v) 72 { 73 p=pre[u]; 74 edge[p].cap-=1; 75 edge[p^1].cap+=1; 76 ans+=edge[p].co; 77 } 78 } 79 int main() 80 { 81 int i,j,k,M; 82 while(~scanf("%d%d",&n,&M)) 83 { 84 memset(head,0,sizeof(head)); 85 s_edge=1; 86 while(M--) 87 { 88 scanf("%d%d%d",&i,&j,&k); 89 addedge(i,j,1,k); 90 addedge(j,i,1,k); 91 } 92 ans=0; 93 for(i=1;i<=2;i++) 94 { 95 spfa(1); 96 end(1,n); 97 } 98 printf("%d\n",ans); 99 } 100 return 0; 101 }
题意:有N个点,从1~N,由两条路从1走到N,要求路径不重复,求两趟所走的最少距离是多少
开始考虑求两次最短路,这个方法不靠谱,因为求完一条最短路把边删掉后,有可能从1到N不在连通
应为最小费流,两点之间的权为费用,容量为1。可以控制股从1到N走两次,也可以建一个超级原点,到1的费用为0,流量为2
代码: