您的位置:首页 > 其它

poj 2135 (费用流) 水题

2014-09-17 19:07 246 查看
题意:FJ有N个农场,M条路,FJ要领朋友游玩,从1走到N,再回到1,不走重复路,每条路长度不一样,问最短路长为多少(无向边)

s到1连边,容量2,费用0 ;

n到汇点t连边,容量2,费用0 ;

其余边容量1,费用为距离 ;

跑一边费用流 ;

#include<cstdio>
#include<cstring>
#include<map>
#include<vector>
#include<cmath>
#include<cstdlib>
#include<stack>
#include<queue>
#include <iomanip>
#include<iostream>
#include<algorithm>
using namespace std ;
const int N= 1500 ;
const int M= 80000 ;
const int inf = 1<< 30 ;

struct node
{
	int u,v,c,cost,next ;
}edge[M] ;
int head
,dist
,pp
,pre
 ,vist
;
int top  ;

void add(int u ,int v,int c,int cost)  
{  
    edge[top].u=u;  
    edge[top].v=v;  
    edge[top].c=c;  
    edge[top].cost=cost;  
    edge[top].next=head[u];  
    head[u]=top++;  
    edge[top].u=v;  
    edge[top].v=u;  
    edge[top].c=0;  
    edge[top].cost=-cost;  
    edge[top].next=head[v];  
    head[v]=top++;  
}  
  
int SPFA(int s,int t)  
{  
    int u , v ;  
    memset(vist,0,sizeof(vist));  
    memset(pre,-1,sizeof(pre));  
    for(int i = 0 ; i <= t ; i++)  dist[i]=inf ;  
    vist[s]=1;dist[s]=0;pre[s]=s;  
    queue<int>q;  
    q.push(s);  
    while(!q.empty())  
    {  
         u=q.front();  
         q.pop();  
         vist[u]=0;  
         for(int i =head[u];i!=-1;i=edge[i].next)  
         {  
               v=edge[i].v;  
               if(edge[i].c && dist[v] > dist[u]+edge[i].cost)  
               {  
                    dist[v] = dist[u]+edge[i].cost ;  
                     pre[v]=u;  
                     pp[v]=i;  
                     if(!vist[v]);  
                     {  
                           vist[v]=1;  
                           q.push(v);  
                     }  
               }  
        }  
    }  
    if(dist[t]==inf) return 0;  
    return 1 ;  
}  
  
int MFMC(int s,int t)  
{  
    int mincost=0,flow=0,minflow ;  
    while(SPFA(s,t))  
    {  
          minflow=inf;  
          for(int i=t;i!=s;i=pre[i])  
              minflow=min(minflow,edge[pp[i]].c);  
          for(int i=t;i!=s;i=pre[i])  
          {  
                edge[pp[i]].c -= minflow;  
                edge[pp[i]^1].c += minflow;  
          }      
          flow += minflow;  
          mincost += dist[t]*minflow ;  
    }  
    return mincost ;  
}  

int main()
{
	 int n,m,u,v,w;
	 while(~scanf("%d%d",&n,&m))
	 {
	 	  top = 0 ;
	 	  memset(head,-1,sizeof(head)) ;
		  for(int i = 1 ; i <= m ; i++)
		  {
		  	   scanf("%d%d%d",&u,&v,&w) ;
		  	   add(u,v,1,w) ;//无向边 
		  	   add(v,u,1,w) ;
		  }
		  int s = 0 ,t=n+1 ;  
	 	  add(s,1,2,0) ;
	 	  add(n,t,2,0) ;
	 	  int ans = MFMC(s,t) ;
	 	  printf("%d\n",ans) ;
	 }
	return 0 ;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: