首页 > 代码库 > 网络流 poj 2135

网络流 poj 2135

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 }

 

网络流 poj 2135