n个点 m条边
给m条边
求1->n n->1 最小花费,每条边最多走一次
两个最短路显然不行 会影响另外一条
1 #include<stdio.h> 2 #include<algorithm> 3 #include<string.h> 4 #include<queue> 5 #include<math.h> 6 7 using namespace std; 8 9 #define inf 100000000 10 #define MAXN 50000 11 #define MAXN1 1500 12 13 struct node 14 { 15 int fr,to,next,fl,w; 16 17 }x[MAXN]; 18 int cnt,S,T; 19 int head[MAXN1],dis[MAXN1],pre[MAXN1]; 20 bool vis[MAXN1]; 21 22 23 void add(int u,int v,int fl,int w) 24 { 25 x[cnt].fr=u; 26 x[cnt].next=head[u]; 27 x[cnt].to=v; 28 x[cnt].fl=fl; 29 x[cnt].w=w; 30 head[u]=cnt++; 31 } 32 queue<int>q1; 33 34 int spfa() //最短路的话就是可以增广 费用最少 35 { 36 memset(vis,0,sizeof(vis)); 37 memset(pre,-1,sizeof(pre)); 38 int i; 39 for(i=0;i<=T;i++) 40 dis[i]=inf; 41 dis[S]=0; 42 vis[S]=1; 43 q1.push(S); 44 while(!q1.empty()) 45 { 46 int now=q1.front(); 47 q1.pop(); 48 vis[now]=0; 49 for(i=head[now];i!=-1;i=x[i].next) 50 { 51 if(dis[now]+x[i].w<dis[x[i].to]&&x[i].fl) 52 { 53 dis[x[i].to]=dis[now]+x[i].w; 54 pre[x[i].to]=i; 55 if(vis[x[i].to]==0) 56 { 57 q1.push(x[i].to); 58 vis[x[i].to]=1; 59 } 60 } 61 } 62 } 63 int a=pre[T]; 64 while(a!=-1) //要结束了也可以更新流量 65 { 66 x[a].fl-=1; 67 x[a^1].fl+=1; 68 a=pre[x[a].fr]; 69 } 70 return pre[T]!=-1; 71 } 72 73 int main() 74 { 75 int n,m; 76 77 while(scanf("%d%d",&n,&m)!=EOF) 78 { 79 int i; 80 cnt=0; 81 memset(head,-1,sizeof(head)); 82 S=0,T=n+1; 83 for(i=1;i<=m;i++) 84 { 85 int a,b,w; 86 87 scanf("%d%d%d",&a,&b,&w); 88 add(a,b,1,w),add(b,a,0,-w); //-w 如果有一条更优的路 可以走回来+(-w); 89 add(b,a,1,w),add(a,b,0,-w); 90 } 91 add(S,1,2,0),add(1,S,0,0); //其实就是2次 1->n 92 add(n,T,2,0),add(T,n,0,0); 93 int ans=0; 94 while(spfa()) 95 ans=ans+dis[T]; 96 printf("%d\n",ans); 97 } 98 return 0; 99 }
原文:http://www.cnblogs.com/cherryMJY/p/6057464.html