码迷,mamicode.com
首页 > 其他好文 > 详细

uva 1658 Admiral 【 最小费用最大流 】

时间:2015-08-17 21:36:04      阅读:132      评论:0      收藏:0      [点我收藏+]

标签:

拆点,每个点拆成 i,i‘

在i 和i‘之间连一条费用为0,容量为1的边,就可以保证每个点只经过一次

特殊的点,1和n之间,,,n和2*n之间连一条费用为0,容量为2的边,可以求出两条路径

技术分享
  1 #include<cstdio>
  2 #include<cstring>
  3 #include<cmath>
  4 #include<iostream>
  5 #include<algorithm>
  6 #include<set>
  7 #include<map>
  8 #include<stack>
  9 #include<vector>
 10 #include<queue>
 11 #include<string>
 12 using namespace std;
 13 
 14 typedef long long LL;
 15 const int maxn = 5000;
 16 const int INF = (1 << 30) - 1;
 17  
 18 int first[maxn],vis[maxn],dis[maxn],pos[maxn],ecnt,size;
 19 
 20 struct Edge{
 21     int v,next,cap,cost;
 22 } e[10*maxn];
 23 
 24 void init(){
 25     ecnt = 0;
 26     memset(first,-1,sizeof(first));
 27 }
 28   
 29 void add_edge(int u,int v,int cap,int cost){
 30     e[ecnt].v = v;
 31     e[ecnt].cap = cap;
 32     e[ecnt].cost = cost;
 33     e[ecnt].next = first[u];
 34     first[u] = ecnt++;
 35     
 36     e[ecnt].v = u;
 37     e[ecnt].cap = 0;
 38     e[ecnt].cost = -cost;
 39     e[ecnt].next = first[v];
 40     first[v] = ecnt++;
 41 }
 42   
 43 bool SPFA(int s, int t)
 44 {
 45     int u,v,i;
 46     queue <int> q;
 47     memset(vis,0,sizeof(vis));
 48     for(i= 0;i <= size;i++) dis[i]=INF;
 49     
 50     dis[s]=0;
 51     vis[s]=1;
 52     q.push(s);
 53     
 54     while(!q.empty()){
 55         u=q.front(); q.pop(); vis[u]=0;
 56         for (i = first[u]; ~i;i = e[i].next){
 57                v=e[i].v; 
 58                if(e[i].cap > 0&& dis[u]+e[i].cost < dis[v]){
 59                   dis[v]=dis[u]+e[i].cost;
 60                   pos[v]=i;
 61                   if(!vis[v]){
 62                      vis[v]=1;
 63                      q.push(v);
 64                   }
 65                }
 66           }
 67     }
 68     return dis[t] != INF;
 69 }
 70 
 71 LL MCMF(int s,int t)
 72 {
 73     int i;
 74     LL cost=0,flow=0;
 75     while(SPFA(s,t)){
 76         int d=INF;
 77         for (i = t;i != s;i = e[pos[i]^1].v){
 78             d = min(d,e[pos[i]].cap);
 79         }
 80         for(i = t;i != s;i = e[pos[i]^1].v){
 81             e[pos[i]].cap -= d;
 82             e[pos[i]^1].cap += d;
 83         }
 84         flow += d;
 85         cost += dis[t]*d;
 86     }
 87     return cost;
 88 }
 89 
 90 
 91 int main(){
 92     int n,m;
 93     while(scanf("%d %d",&n,&m) != EOF){
 94         init();
 95         size = 2*n+1;
 96         add_edge(1,1+n,2,0);
 97         add_edge(n,2*n,2,0);
 98         for(int i = 2;i < n;i++) add_edge(i,i+n,1,0);
 99         
100         for(int i = 0;i < m;i++){
101             int u,v,w;
102             scanf("%d %d %d",&u,&v,&w);
103             add_edge(u+n,v,1,w);
104         }
105         printf("%lld\n",MCMF(1,2*n));
106     }
107     return 0;
108 }
View Code

 

uva 1658 Admiral 【 最小费用最大流 】

标签:

原文地址:http://www.cnblogs.com/wuyuewoniu/p/4737479.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!