zoukankan      html  css  js  c++  java
  • POJ 2135 【最小费用最大流】.cpp

    题意:

    给出m个路径的起点和终点还有长度

    找出一条路径可以从1到n然后回到1..

    并保证找到的路径是不重复而且是最短的..

     

    思路:

    容量控制经过只有1次

    费用控制长度

    在建完图后求最小费用最大流..

    就可以找出最短距离..而且没有重复路径..

     

    Tips:

    ※ 0点作为超级源点和1相连   n+1作为超级汇点和n相连    然后容量为2费用为0 保证一进一出

    ※ 建图的时候..相邻的正反边要紧挨着写..

      因为更改图中的容量的时候..

        edge[load[u]].c -= mn;

            edge[load[u]^1].c += mn;

        位运算表示的是反向边..所以加的时候应该紧挨着加..

    ※ 加边的时候..除了加已知的边 还要加入反向边 同时要加入容量为0 费用为负值的边..

      所以每次运算的时候..应该先加入一条正向边 然后加入正向边的反向负值边

                然后加入一条反向边 再加入反向边的反向负值边

    Code:

    View Code
      1 #include <stdio.h>
      2 #include <cstring>
      3 #include <algorithm>
      4 using namespace std;
      5 #define clr(x) memset(x, 0, sizeof(x))
      6 const int INF = 0x1f1f1f1f;
      7 const int MAXN = 1010;
      8 const int MAXM = 100010;
      9 struct Edge
     10 {
     11     int to;
     12     int next;
     13     int c;
     14     int f;
     15 }edge[MAXM];
     16 int head[MAXN];
     17 int tot;
     18 int n;
     19 int dis[MAXN], load[MAXN], p[MAXN];
     20 bool flag[MAXN];
     21 
     22 void add(int s, int u, int c, int f)
     23 {
     24     edge[tot].to = u;
     25     edge[tot].next = head[s];
     26     edge[tot].f = f;
     27     edge[tot].c = c;
     28     head[s] = tot++;
     29 }
     30 
     31 bool spfa(int s, int en)
     32 {
     33     int que[MAXN*10], qout, qin;
     34     clr(flag);
     35     memset(p, 0xff, sizeof(p));
     36     memset(load, 0xff, sizeof(load));
     37     memset(dis, INF, sizeof(dis));
     38     qin = qout = 0;
     39     que[qin++] = s;
     40     dis[s] = 0;
     41     flag[s] = true;
     42     while(qin != qout) {
     43         int e = que[qout++];
     44         flag[e] = false;
     45         for(int i = head[e]; i != -1; i=edge[i].next) {
     46             if(edge[i].c) {
     47                 int ne = edge[i].to;
     48                 if(dis[ne]-dis[e] > edge[i].f) {
     49                     dis[ne] = dis[e]+edge[i].f;
     50                     p[ne] = e;
     51                     load[ne] = i;
     52                     if(!flag[ne]) {
     53                         flag[ne] = true;
     54                         que[qin++] = ne;
     55                     }
     56                 }
     57             }
     58         }
     59     }
     60     if(dis[en] == INF)
     61         return false;
     62     else return true;
     63 }
     64 
     65 int min_c_f(int s, int e)
     66 {
     67     int u, mn;
     68     int ans_f = 0, ans_c = 0;
     69     while(spfa(s, e))
     70     {
     71         u = e;
     72         mn = INF;
     73         while(p[u] != -1) {
     74             mn = min(edge[load[u]].c, mn);
     75             u = p[u];
     76         }
     77         u = e;
     78         while(p[u] != -1) {
     79             edge[load[u]].c -= mn;
     80             edge[load[u]^1].c += mn;
     81             u = p[u];
     82         }
     83         ans_f += dis[e]*mn;
     84         ans_c += mn;
     85     }
     86     return ans_f;
     87 }
     88 
     89 int main()
     90 {
     91     int i, j, k;
     92     int m;
     93     int a, b, l;
     94     while(scanf("%d %d", &n, &m) != EOF)
     95     {
     96         clr(load), clr(dis), clr(p);
     97         memset(head, 0xff, sizeof(head));
     98         tot = 0;
     99 
    100         while(m--) {
    101             scanf("%d %d %d", &a, &b, &l);
    102             add(a, b, 1, l);
    103             add(b, a, 0, -l);
    104             add(b, a, 1, l);
    105             add(a, b, 0, -l);
    106         }
    107 
    108         add(0, 1, 2, 0);
    109         add(1, 0, 2, 0);
    110         add(n, n + 1, 2, 0);
    111         add(n+1, n , 2, 0);
    112         int ans = min_c_f(0, n+1);
    113         printf("%d\n", ans);
    114     }
    115     return 0;
    116 }

     

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

  • 相关阅读:
    day10作业
    day9 函数作业
    Python编码及文件练习题
    day10函数命名空间,嵌套,闭包
    Python基础数据类型考试题
    day9 函数
    day8 文件操作
    day7 集合
    day6 编码
    day5 作业自我完成版
  • 原文地址:https://www.cnblogs.com/Griselda/p/2710005.html
Copyright © 2011-2022 走看看