zoukankan      html  css  js  c++  java
  • 【费用流】bzoj1877: [SDOI2009]晨跑

    题是费用流的板子题;写的时候拆点部分搞混了一会儿

    Description

    Elaxia最近迷恋上了空手道,他为自己设定了一套健身计划,比如俯卧撑、仰卧起坐等 等,不过到目前为止,他
    坚持下来的只有晨跑。 现在给出一张学校附近的地图,这张地图中包含N个十字路口和M条街道,Elaxia只能从 一
    个十字路口跑向另外一个十字路口,街道之间只在十字路口处相交。Elaxia每天从寝室出发 跑到学校,保证寝室
    编号为1,学校编号为N。 Elaxia的晨跑计划是按周期(包含若干天)进行的,由于他不喜欢走重复的路线,所以 
    在一个周期内,每天的晨跑路线都不会相交(在十字路口处),寝室和学校不算十字路 口。Elaxia耐力不太好,
    他希望在一个周期内跑的路程尽量短,但是又希望训练周期包含的天 数尽量长。 除了练空手道,Elaxia其他时间
    都花在了学习和找MM上面,所有他想请你帮忙为他设计 一套满足他要求的晨跑计划。

    Input

    第一行:两个数N,M。表示十字路口数和街道数。 
    接下来M行,每行3个数a,b,c,表示路口a和路口b之间有条长度为c的街道(单向)。
    N ≤ 200,M ≤ 20000。

    Output

    两个数,第一个数为最长周期的天数,第二个数为满足最长天数的条件下最短的路程长 度。


    题目分析

    为表示只经过一次的限制,和bzoj1711一样拆点处理,即连一条流量为1,费用为0的边。那么剩下的就是费用流的板子:以路程为费用;天数为流量建图。

    小细节:源汇点与1,n连边时,为表示1,n有无限容量需要连$(S,1+n),(n+n,T)$.

     1 #include<bits/stdc++.h>
     2 const int maxn = 503;
     3 const int maxm = 50035;
     4 const int INF = 2e9;
     5 
     6 struct Edge
     7 {
     8     int u,v,f,c,cst;
     9     Edge(int a=0, int b=0, int c=0, int d=0, int e=0):u(a),v(b),f(c),c(d),cst(e) {}
    10 }edges[maxm];
    11 int n,m,S,T;
    12 bool inq[maxn];
    13 int bck[maxn],cst[maxn],flw[maxn];
    14 int edgeTot,head[maxn],nxt[maxm];
    15 
    16 int read()
    17 {
    18     char ch = getchar();
    19     int num = 0, fl = 1;
    20     for (; !isdigit(ch); ch=getchar())
    21         if (ch=='-') fl = -1;
    22     for (; isdigit(ch); ch=getchar())
    23         num = (num<<1)+(num<<3)+ch-48;
    24     return num*fl;
    25 }
    26 void addedge(int u, int v, int cap, int cst)
    27 {
    28     edges[edgeTot] = Edge(u, v, 0, cap, cst), nxt[edgeTot] = head[u], head[u] = edgeTot++;
    29     edges[edgeTot] = Edge(v, u, 0,  0, -cst), nxt[edgeTot] = head[v], head[v] = edgeTot++;
    30 }
    31 void maxFlow()
    32 {
    33     int mxFlw = 0, cost = 0;
    34     for (;;)
    35     {
    36         std::queue<int> q;
    37         memset(flw, 0, sizeof flw);
    38         memset(bck, 0, sizeof bck);
    39         memset(cst, 0x3f3f3f3f, sizeof cst);
    40         q.push(S), flw[S] = INF, cst[S] = 0;
    41         for (int tmp; q.size(); )
    42         {
    43             tmp = q.front(), q.pop(), inq[tmp] = 0;
    44             for (int i=head[tmp]; i!=-1; i=nxt[i])
    45             {
    46                 int v = edges[i].v;
    47                 if (cst[tmp]+edges[i].cst < cst[v]&&edges[i].f < edges[i].c){
    48                     bck[v] = i, cst[v] = cst[tmp]+edges[i].cst;
    49                     flw[v] = std::min(flw[tmp], edges[i].c-edges[i].f);
    50                     if (!inq[v]) inq[v] = 1, q.push(v);
    51                 }
    52             }
    53         }
    54         if (!flw[T]) break;
    55         for (int i=T; i!=S; i=edges[bck[i]].u)
    56             edges[bck[i]].f += flw[T], edges[bck[i]^1].f -= flw[T];
    57         mxFlw += flw[T], cost += cst[T]*flw[T];
    58     }
    59     printf("%d %d
    ",mxFlw,cost);
    60 }
    61 int main()
    62 {
    63     memset(head, -1, sizeof head);
    64     n = read(), m = read(), S = 0, T = 2*n+2;
    65     for (int i=1; i<=m; i++)
    66     {
    67         int u = read(), v = read(), cst = read();
    68         addedge(u+n, v, 1, cst);
    69     }
    70     for (int i=1; i<n; i++) addedge(i, i+n, 1, 0);
    71     addedge(S, n+1, INF, 0), addedge(n, T, INF, 0);
    72     maxFlow();
    73     return 0;
    74 } 

    END

  • 相关阅读:
    机器学习 之 SVM VC维度、样本数目与经验风险最小化的关系
    password学4——Java 加密解密之消息摘要算法(MD5 SHA MAC)
    JavaScript实现类的private、protected、public、static以及继承
    android:3D垂直翻转动画-FlipAnimation
    生产者消费者问题
    01串
    html5+css3 权威指南阅读笔记(三)---表单及其它新增和改良元素
    Android xUtils3源代码解析之网络模块
    mysql5.7切换导致gtid不一致
    mysql简单优化的一些总结
  • 原文地址:https://www.cnblogs.com/antiquality/p/10354139.html
Copyright © 2011-2022 走看看