POJ 2135 最小费用流模板题

题目大意:

从起点1到终点N的一个圈,最小路径花费。完毕。

构图跑两次spfa,完毕。

#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<queue>
#include<cmath>
#include<algorithm>
#define NN 1111
#define MN 11111
using namespace std;

struct Edge{ int u,v,c,f,cost,next; }E[MN<<2];
int head[NN],dis[NN],cur[NN],pre[NN];
int EN,s,t;
bool vis[NN];

void addEdge( int u,int v,int c,int cost )
{
 	 E[EN].v=v; E[EN].c=c; E[EN].f=0; E[EN].cost=cost;
 	 E[EN].next=head[u]; head[u]=EN++;
 	 E[EN].v=u; E[EN].c=0; E[EN].f=0; E[EN].cost=-cost;
 	 E[EN].next=head[v]; head[v]=EN++;
}

void spfa()
{
 	 memset( vis,0,sizeof(vis) );
 	 memset( dis,0x3f,sizeof(dis) );
 	 queue<int>Q;
 	 dis[s]=0;pre[s]=s;
 	 Q.push(s);
 	 while( !Q.empty() )
 	 {
	  		int cc=Q.front();Q.pop();
	  		vis[cc]=false;
	  		for( int i=head[cc];i!=-1;i=E[i].next )
	  		{
			 	 if( dis[E[i].v]>dis[cc]+E[i].cost && E[i].f<E[i].c )
			 	 {
				  	 dis[E[i].v]=dis[cc]+E[i].cost;
				  	 pre[E[i].v]=cc;
				  	 cur[E[i].v]=i;
				  	 if( !vis[E[i].v] )
		  	 	 	 {
					  	 Q.push(E[i].v);
					  	 vis[E[i].v]=true;
 	 			  	 }
			   	 }
 	 	 	}
	 }
}

int main()
{
 	int N,M;
 	while( scanf("%d %d",&N,&M)!=EOF )
 	{
	 	   int u,v,cost;
	 	   memset( head,-1,sizeof(head) );
	 	   s=0;t=N+1;
	 	   for( int i=0;i<M;i++ )
	 	   {
	 	   		scanf( "%d %d %d",&u,&v,&cost );
	 	   		addEdge( u,v,1,cost );
	 	   		addEdge( v,u,1,cost );
		   }
		   addEdge( s,1,2,0 ); addEdge( N,t,2,0 );
		   int ans=0;
		   while( true )
		   {
		   		  spfa();
		   		  int aug=0x3f3f3f3f;
		   		  if( dis[t]==0x3f3f3f3f )
		   		  	  break;
		   		  for( int i=t;i!=s;i=pre[i] )
		   		  	   aug=min( aug,E[cur[i]].c-E[cur[i]].f );
		   		  for( int i=t;i!=s;i=pre[i] )
 		  	   	  {
				   	   E[cur[i]].f+=aug;
				   	   E[cur[i]^1].f-=aug;
			  	  }
		   		  ans+=aug*dis[t];
 		   }
 		   printf( "%d\n",ans );
  	}
  	return 0;
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值