POJ 2135-最小费用最大流

链接:http://poj.org/problem?id=2135

这道题数据范围给的很坑爹啊,题面给的1000,我开到1500都过不了,RE了一个小时,最后实在没办法,开到2000,一下子A了,真想说一句:fuck!!

要求不能有重复的路径,路径的长度为费用,每条路径的流值为1,并且建立超级源点和超级汇点,从超级源点连接到0一个流值为2,费用为0的边,n和超级汇点也连这么一条边,因为是无向图,所以要加四条边,而且只能用邻接表的实现。

剩下的是最小费用流的模板,spfa()找最短路径

View Code
  1 #include<iostream>
  2 #include<cstdio>
  3 #include<cstring>
  4 #define N 2005
  5 #define M 10005
  6 #define inf 1<<30
  7 using namespace std;
  8 bool used[N];
  9 int head[N],t;
 10 int que[N],d[N];
 11 int pre[N];
 12 struct node
 13 {
 14     int u,v,next,cost,flow;
 15 };
 16 node e[M*4];
 17 void add(int u,int v,int f,int c)
 18 {
 19     e[t].u=u;
 20     e[t].v=v;
 21     e[t].flow=f;
 22     e[t].cost=c;
 23     e[t].next=head[u];
 24     head[u]=t++;
 25     e[t].v=u;
 26     e[t].u=v;
 27     e[t].flow=0;
 28     e[t].cost=-c;
 29     e[t].next=head[v];
 30     head[v]=t++;
 31 }
 32 void init()
 33 {
 34     memset(head,-1,sizeof(head));
 35     t=0;
 36 }
 37 bool spfa(int num,int to)
 38 {
 39     int f,r,u,v,i,j;
 40     memset(used,0,sizeof(used));
 41     memset(pre,-1,sizeof(pre));
 42     f=r=0;
 43     for(i=0;i<=num;i++)
 44     d[i]=inf;
 45     used[0]=true;
 46     que[r++]=0;
 47     d[0]=0;
 48     while(f!=r)
 49     {
 50         u=que[f++];
 51         used[u]=false;
 52         for(i=head[u];i>=0;i=e[i].next)
 53         {
 54             v=e[i].v;
 55             if(e[i].flow!=0&&d[v]>d[u]+e[i].cost)
 56             {
 57                 pre[v]=i;
 58                 d[v]=d[u]+e[i].cost;
 59                 if(!used[v])
 60                 {
 61                     used[v]=true;
 62                     que[r++]=v;
 63                 }
 64             }
 65         }
 66     }
 67     if(pre[to]==-1)
 68     return false;
 69     return true;
 70 }
 71 int solve(int num,int to)
 72 {
 73     int ans=0,minflow;
 74     int i,j,v;
 75     while(spfa(num,to))
 76     {
 77         minflow=inf;
 78         for(i=pre[to];i!=-1;i=pre[e[i].u])
 79         {
 80             if(minflow>e[i].flow)
 81             minflow=e[i].flow;
 82         }
 83         for(i=pre[to];i!=-1;i=pre[e[i].u])
 84         {
 85             e[i].flow-=minflow;
 86             e[i^1].flow+=minflow;
 87             ans+=(minflow*e[i].cost);
 88         }
 89     }
 90     return ans;
 91 }
 92 int main()
 93 {
 94     int n,m,i,j,u,v,c;
 95     scanf("%d%d",&n,&m);
 96     init();
 97     add(0,1,2,0);
 98     add(n,n+1,2,0);
 99     while(m--)
100     {
101         scanf("%d%d%d",&u,&v,&c);
102         add(u,v,1,c);
103         add(v,u,1,c);
104     }
105     printf("%d\n",solve(n+1,n+1));
106     return 0;
107 }

 

posted @ 2012-08-23 21:27  zhenhai  阅读(229)  评论(0)    收藏  举报