zoukankan      html  css  js  c++  java
  • 1927. [SDOI2010]星际竞速【费用流】

    Description

      10年一度的银河系赛车大赛又要开始了。作为全银河最盛大的活动之一,夺得这个项目的冠军无疑是很多人的
    梦想,来自杰森座α星的悠悠也是其中之一。赛车大赛的赛场由N颗行星和M条双向星际航路构成,其中每颗行星都
    有一个不同的引力值。大赛要求车手们从一颗与这N颗行星之间没有任何航路的天体出发,访问这N颗行星每颗恰好
    一次,首先完成这一目标的人获得胜利。由于赛制非常开放,很多人驾驶着千奇百怪的自制赛车来参赛。这次悠悠
    驾驶的赛车名为超能电驴,这是一部凝聚了全银河最尖端科技结晶的梦幻赛车。作为最高科技的产物,超能电驴有
    两种移动模式:高速航行模式和能力爆发模式。在高速航行模式下,超能电驴会展开反物质引擎,以数倍于光速的
    速度沿星际航路高速航行。在能力爆发模式下,超能电驴脱离时空的束缚,使用超能力进行空间跳跃——在经过一
    段时间的定位之后,它能瞬间移动到任意一个行星。天不遂人愿,在比赛的前一天,超能电驴在一场离子风暴中不
    幸受损,机能出现了一些障碍:在使用高速航行模式的时候,只能由每个星球飞往引力比它大的星球,否则赛车就
    会发生爆炸。尽管心爱的赛车出了问题,但是悠悠仍然坚信自己可以取得胜利。他找到了全银河最聪明的贤者——
    你,请你为他安排一条比赛的方案,使得他能够用最少的时间完成比赛。

    Input

      第一行是两个正整数N,M。第二行N个数A1~AN,其中Ai表示使用能力爆发模式到达行星i所需的定位时间。接下
    来M行,每行3个正整数ui,vi,wi,表示在编号为ui和vi的行星之间存在一条需要航行wi时间的星际航路。输入数据
    已经按引力值排序,也就是编号小的行星引力值一定小,且不会有两颗行星引力值相同。

    Output

      仅包含一个正整数,表示完成比赛所需的最少时间。

    Sample Input

    3 3
    1 100 100
    2 1 10
    1 3 1
    2 3 1

    Sample Output

    12

    HINT

      说明:先使用能力爆发模式到行星1,花费时间1。然后切换到高速航行模式,航行到行星2,花费时间10。之

    后继续航行到行星3完成比赛,花费时间1。虽然看起来从行星1到行星3再到行星2更优,但我们却不能那样做,因

    为那会导致超能电驴爆炸。N≤800,M≤15000。输入数据中的任何数都不会超过106。输入数据保证任意两颗行星

    之间至多存在一条航道,且不会存在某颗行星到自己的航道。

    blog.csdn.net/lerbon23james/article/details/79479416
    觉得上面那篇博客写的还算详细……
    感觉自己现在建模的能力为0
    一开始想到拆点了,只不过对于跳跃我是搞了一个类似传送站的东西
    上去的费用为0,下来的为边权。可是这样没法保证每个点都通过……
    像blog里写的方法,因为最大流一定是n,
    又因为解法类似最小路径覆盖,
    所以能够保证n个点都经过一次

     1 #include<iostream>
     2 #include<cstdio>
     3 #include<cstdlib>
     4 #include<cstring>
     5 #include<queue>
     6 #define MAXN (10000+10)
     7 #define MAXM (1000000+10)
     8 using namespace std; 
     9 bool visit[MAXN];
    10 int pre[MAXN];
    11 int n,m,s,e,z,Ans,a[MAXN];
    12 int num_edge;
    13 int head[MAXN];
    14 int dis[MAXN];
    15 bool used[MAXN];
    16 int INF;
    17 queue<int>q;
    18 struct node
    19 {
    20     int to;
    21     int next;
    22     int Flow;//残留网络 
    23     int Cost;
    24 }edge[MAXM*2];
    25 
    26 void add(int u,int v,int l,int c)
    27 {
    28     edge[++num_edge].to=v;
    29     edge[num_edge].next=head[u];
    30     edge[num_edge].Flow=l;
    31     edge[num_edge].Cost=c;
    32     head[u]=num_edge;    
    33 }
    34 
    35 bool Spfa(int s,int e)
    36 {
    37     memset(dis,0x7f,sizeof(dis));
    38     memset(pre,-1,sizeof(pre));
    39     dis[s]=0;
    40     used[s]=true;
    41     q.push(s);
    42     while (!q.empty())
    43     {
    44         int x=q.front(); q.pop();
    45         for (int i=head[x];i!=0;i=edge[i].next)
    46             if (dis[x]+edge[i].Cost<dis[edge[i].to] && edge[i].Flow>0)
    47             {
    48                 dis[edge[i].to]=dis[x]+edge[i].Cost;
    49                 pre[edge[i].to]=i;
    50                 if (!used[edge[i].to])
    51                 {
    52                     used[edge[i].to]=true;
    53                     q.push(edge[i].to);
    54                 }
    55             }
    56         used[x]=false;
    57     }
    58     return dis[e]!=INF;
    59 }
    60 
    61 int MCMF(int s,int e)
    62 {
    63     int Fee=0;
    64     while (Spfa(s,e))
    65     {
    66         int d=INF;
    67         for (int i=e;i!=s;i=edge[((pre[i]-1)^1)+1].to)
    68             d=min(d,edge[pre[i]].Flow);
    69         for (int i=e;i!=s;i=edge[((pre[i]-1)^1)+1].to)
    70         {
    71             edge[pre[i]].Flow-=d;
    72             edge[((pre[i]-1)^1)+1].Flow+=d;
    73         }
    74         Fee+=d*dis[e];
    75     }
    76     return Fee;
    77 }
    78 
    79 int main()
    80 {
    81     memset(&INF,0x7f,sizeof(INF));
    82     s=0,e=10001;
    83     scanf("%d%d",&n,&m);
    84     for (int i=1;i<=n;++i)
    85     {
    86         scanf("%d",&a[i]);
    87         add(s,i+n,1,a[i]); add(i+n,s,0,-a[i]);
    88         add(s,i,1,0); add(i,s,0,0);
    89         add(i+n,e,1,0); add(e,i+n,0,0);
    90     }
    91     int u,v,l;
    92     for (int i=1;i<=m;++i)
    93     {
    94         scanf("%d%d%d",&u,&v,&l);
    95         if (u>v) swap(u,v);
    96         add(u,v+n,1,l); add(v+n,u,0,-l);
    97     }
    98     printf("%d",MCMF(s,e));
    99 }
  • 相关阅读:
    Do You See Me? Ethical Considerations of the Homeless
    ELDER HOMELESSNESS WHY IS THIS AN ISSUE?
    Endoflife support is lacking for homeless people
    html内联框架
    html字体
    html块 div span
    html列表
    html表格
    SQL Server管理员专用连接的使用   作为一名DBA,经常会处理一些比较棘手的服务无响应问题,鉴于事态的严重性,多数DBA可能直接用“重启”大法,以便尽快的恢复生产环境的正常运转,但是多数情况
    如何配置最大工作线程数 (SQL Server Management Studio)
  • 原文地址:https://www.cnblogs.com/refun/p/8681180.html
Copyright © 2011-2022 走看看