zoukankan      html  css  js  c++  java
  • 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 }
  • 相关阅读:
    POJ 2253 Frogger(最短路 Floyd)
    POJ 1062 昂贵的聘礼 (最短路 Dijkstra)
    POJ 3259 Wormholes(最短路Bellman_Ford)
    POJ 3414 Pots(容量BFS)
    POJ 3087 Shuffle'm Up(模拟题)
    POJ 3216 Prime Path(数字BFS)
    refresh的停车场
    基于邻接表的广度优先搜索遍历
    判断给定图是否存在合法的拓扑排序
    威威猫系列故事——篮球梦
  • 原文地址:https://www.cnblogs.com/caozhenhai/p/2653285.html
Copyright © 2011-2022 走看看