zoukankan      html  css  js  c++  java
  • 习题:codevs 1035 火车停留解题报告

    本蒟蒻又来写解题报告了。这次的题目是codevs 1035 火车停留。

    题目大意就是给m个火车的到达时间、停留时间和车载货物的价值,车站有n个车道,而火车停留一次车站就会从车载货物价值中获得1%的利润,让你来求一种安排方法,使得车站收益最大,并输出收益值。

    蒟蒻的思路是这样的:

    一眼看出:最大费用最大流(MCMF)
    显然cost:表示车站收益
    然后……
    以车站为点建立图求流?同一个车站可能经过好几辆火车……,貌似很麻烦……;
    那么以什么建图、连边,还有怎么连?
    貌似有点类似于方格取数2之中的拆点……;
    那么这个就可以……以火车为点,把一个点拆成两个,然后建立流的关系。
    Reach[i]和stay[i]作为建立不同火车是否可以建边的判断条件
    假设火车i,将其分为点2*i-1和2*i,连一条流量为1,费用为-cost[i]的边
    如果reach[i] + stay[i] < reach[j],在2*i和2*j-1之间连一条流量为1,费用为0的边。
    建立汇点和起点S,T,从S向每个2*i-1连一条流量为1,费用为0的边。从每个2*i向T连一条流量为1,费用为0的边。

    那么怎么限制n个车道呢?其实很简单,只需要建立超级汇点ST,然后从T向ST连一条流量为n,费用为0的边。

    这样这个题目就大功告成了,代码不长,刚98行。建议大家还是去刷一下代码能力题,因为NOIP2015蒟蒻就被代码能力题给坑惨了。

    废话不多说,上代码

     1 #include <iostream>
     2 #include <cstdio>
     3 #include <cstring>
     4 #include <cmath>
     5 #include <algorithm>
     6 #include <queue>
     7 using namespace std;
     8 const int INF = 10000000;
     9 const int maxe = 10000;
    10 const int maxn = 500;
    11 int n,m,reach[maxn],stay[maxn],cost[maxn],vis[maxn<<1],d[maxn<<1],h[maxn<<1],pre[maxn<<1],rid[maxn],cid[maxn],now;
    12 double ans;
    13 struct edge{
    14     int to,cost,cap,next;
    15 }tr[maxe];
    16 inline void init(){
    17     now = 0;
    18     memset(h,-1,sizeof(h));
    19     memset(tr,0,sizeof(tr));
    20     memset(reach,0,sizeof(reach));
    21     memset(stay,0,sizeof(stay));
    22     memset(cost,0,sizeof(cost));
    23 }
    24 inline void add(int u,int v,int cap,int cost){
    25     tr[now].to = v;tr[now].cap = cap;tr[now].cost = cost;tr[now].next = h[u];
    26     h[u] = now++;
    27     tr[now].to = u;tr[now].cap = 0;tr[now].cost = -cost;tr[now].next = h[v];
    28     h[v] = now++;
    29 }
    30 bool SPFA(int s,int t,int &flow,int &cost){
    31     for(int i = s;i <= t;++i){
    32         d[i] = INF;
    33     }
    34     int minflow = INF;
    35     memset(vis,0,sizeof(vis));
    36     memset(pre,-1,sizeof(pre));
    37     deque<int>q;
    38     d[s] = 0;
    39     vis[s] = 1;
    40     q.push_back(s);
    41     while(!q.empty()){
    42         int x = q.front();q.pop_front();
    43         vis[x] = 0;
    44         for(int i = h[x];i != -1;i = tr[i].next){
    45             edge e = tr[i];
    46             if(d[e.to] > d[x] + e.cost && e.cap){
    47                 d[e.to] = d[x] + e.cost;
    48                 pre[e.to] = i;
    49                 minflow = min(minflow,e.cap);
    50                 if(!vis[e.to]){
    51                     vis[e.to] = 1;
    52                     q.push_back(e.to);
    53                 }
    54             }
    55         }
    56     }
    57     if(d[t] == INF)return false;
    58     flow += minflow;
    59     cost += d[t] * minflow;
    60     for(int i = t;i != s;i = tr[pre[i]^1].to){
    61         tr[pre[i]].cap -= minflow;
    62         tr[pre[i]^1].cap += minflow;
    63     }
    64     return true;
    65 }
    66 int MCMF(int s,int t){
    67     int flow = 0,cost = 0;
    68     while(SPFA(s,t,flow,cost));
    69     return cost;
    70 }
    71 int main(){
    72     scanf("%d%d",&n,&m);
    73     init();
    74     for(int i = 1;i <= m;++i){
    75         scanf("%d%d%d",&reach[i],&cost[i],&stay[i]);
    76         rid[i] = 2*i;cid[i] = 2*i-1;
    77         add(cid[i],rid[i],1,-cost[i]);
    78     }
    79     for(int i = 1;i <= m;++i){
    80         for(int j = 1;j <= m;++j){
    81             if(j != i)
    82                 if(reach[i] + stay[i] < reach[j]){
    83                     add(rid[i],cid[j],1,0);
    84                 }
    85         }
    86     }
    87     int S = 0,T = 2*m+1,ST = 2*m+2;
    88     for(int i = 1;i <= m;++i){
    89         add(S,cid[i],1,0);
    90     }
    91     for(int i = 1;i <= m;++i){
    92         add(rid[i],T,1,0);
    93     }
    94     add(T,ST,n,0);
    95     ans = double(MCMF(S,ST))/100;
    96     printf("%0.2lf
    ",-ans);
    97     return 0;
    98 }

    如果大家认为有用的话,欢迎转载。如果大家有意见的话,请在下方评论栏中给我留言,或者给我的E-mail PC-worker@outlook.com发邮件留言。谢谢大家。

  • 相关阅读:
    shell文本过滤编程(一):grep和正则表达式【转】
    从头开始写项目Makefile(十):make内嵌函数及make命令显示【转】
    写文章 TEE技术分析【转】
    移动电子商务:五个技术标准与Trustonic TEE解决方案【转】
    在vscode中使用pylint-django插件解决pylint的一些不必要的错误提示【转】
    从零开始学习OpenCL开发(一)架构【转】
    一张图让你学会Python【转】
    关于ping以及TTL的分析【转】
    g++的编译选项:-Wl,-rpath=【转】
    【梦幻连连连】源代码分析(四)-触摸处理
  • 原文地址:https://www.cnblogs.com/gangding/p/5648078.html
Copyright © 2011-2022 走看看