zoukankan      html  css  js  c++  java
  • POJ2135 来回最短路(简单费用流)

    题意:
          就是从1走到n然后再走回来,一条边只能走一次,要求路径最短。

    思路:
          比较水,可以直接一遍费用流,不解释了,具体的看看代码,敲这个题就是为了练

    练手,好久不敲了,怕比赛手生。

     

    #include<queue>
    #include<stdio.h>
    #include<string.h>

    #define N_node 1000 + 10
    #define N_edge 40000 + 20
    #define INF 100000000

    using namespace std;

    typedef struct
    {
       int from ,to ,cost ,flow ,next;
    }STAR;

    STAR E[N_edge];
    int list[N_node] ,tot;
    int mer[N_edge];
    int s_x[N_node];

    void add(int a ,int b ,int c ,int d)
    {
         E[++tot].from = a;
         E[tot].to = b;
         E[tot].cost = c;
         E[tot].flow = d;
         E[tot].next = list[a];
         list[a] = tot;
        
         E[++tot].from = b;
         E[tot].to = a;
         E[tot].cost = -c;
         E[tot].flow = 0;
         E[tot].next = list[b];
         list[b] = tot;
    }

    bool Spfa(int s ,int t ,int n)
    {
        int mark[N_node] = {0};
        for(int i = 0 ;i <= n ;i ++) s_x[i] = INF;
        mark[s] = 1 ,s_x[s] = 0;
        queue<int>q;
        q.push(s);
        memset(mer ,255 ,sizeof(mer));
        while(!q.empty())
        {
            int xin ,tou = q.front();
            q.pop();
            mark[tou] = 0;
            for(int k = list[tou] ;k ;k = E[k].next)
            {
                xin = E[k].to;
                if(s_x[xin] > s_x[tou] + E[k].cost && E[k].flow)
                {
                    s_x[xin] = s_x[tou] + E[k].cost;
                    mer[xin] = k;
                    if(!mark[xin])
                    {
                        mark[xin] = 1;
                        q.push(xin);
                    }
                }
            }
        }
        return mer[t] != -1;
    }

    int M_C_Flow(int s ,int t ,int n)
    {
       int maxflow = 0 ,mincost = 0 ,minflow;
       while(Spfa(s ,t ,n))
       {
           minflow = INF;
           for(int i = mer[t] ;i + 1 ;i = mer[E[i].from])
           if(minflow > E[i].flow) minflow = E[i].flow;
           for(int i = mer[t] ;i + 1 ;i = mer[E[i].from])
           {
               E[i].flow -= minflow;
               E[i^1].flow += minflow;
               mincost += minflow * E[i].cost;
           }
           maxflow += minflow;
       }
       return mincost;
    }

    int main ()
    {
        int n ,m ,i ,a ,b ,c;
        while(~scanf("%d %d" ,&n ,&m))
        {
           memset(list ,0 ,sizeof(list)) ,tot = 1;
           for(i = 1 ;i <= m ;i ++)
           {
              scanf("%d %d %d" ,&a ,&b ,&c);
              add(a ,b ,c ,1);
              add(b ,a ,c ,1);
           }
           add(0 ,1 ,0 ,2);
           add(n ,n + 1 ,0 ,2);
           printf("%d " ,M_C_Flow(0 ,n + 1 ,n + 1));
        }
        return 0;
    }
             

     

     


       
       
       
       
        

     

     

     

     

     

     

     

  • 相关阅读:
    怎么在一个线程结束后回到主线程?
    iOS KVC & KVO
    iOS添加到购物车的简单动画效果
    如何在键盘出现时滚动表格,以适应输入框的显示
    iOS开发之多媒体播放
    算法的时间复杂度(一)
    SPI通信
    三级管的原理
    stm32之595(spi芯片)
    stm32之Systick(系统时钟)
  • 原文地址:https://www.cnblogs.com/csnd/p/12062707.html
Copyright © 2011-2022 走看看