poj 2135 (费用流) 水题

来源:互联网 发布:淘宝智能客服 编辑:程序博客网 时间:2024/05/17 22:50
题意: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[N],dist[N],pp[N],pre[N] ,vist[N];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 ;} 




0 0