zoukankan      html  css  js  c++  java
  • C++之路进阶——codevs2313(星际竞速)

    2313 星际竞速

     

    2010年省队选拔赛山东

     时间限制: 3 s
     空间限制: 128000 KB
     题目等级 : 大师 Master
     
     
    题目描述 Description

    10 年一度的银河系赛车大赛又要开始了。作为全银河最盛大的活动之一,夺得这个项目的冠军无疑是很多人的梦想,来自杰森座 α星的悠悠也是其中之一。

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

    输入描述 Input Description

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

    输出描述 Output Description

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

    样例输入 Sample Input

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

    样例输出 Sample Output

    12 

    数据范围及提示 Data Size & Hint

    对于 30%的数据 N≤20,M≤50; 
    对于 70%的数据 N≤200,M≤4000; 
    对于100%的数据N≤800, M≤15000。输入数据中的任何数都不会超过106
    。 
    输入数据保证任意两颗行星之间至多存在一条航道,且不会存在某颗行星到
    自己的航道。

    题解:

       拆点,最小费用最大流。将源点与所有点拆出来的连边,费用为a[i],与原来的点连连边,花费为0.将拆出来的点与所有的汇点连边,费用为0,将路径的起点与路径终点拆出来的点相连,花费权值。

    代码:

       

      1 #include<cstdio>
      2 #include<iostream>
      3 #include<algorithm>
      4 #include<cstring>
      5 #include<cmath>
      6 #include<queue>
      7 #define maxn 10065
      8 #define inf 0x7fffffff
      9 
     10 using namespace std;
     11 
     12 int head[maxn],dis[maxn],a[maxn],cnt=1,from[maxn],n,m,inq[maxn],ans,T;
     13 
     14 struct ss
     15    {
     16        int to;
     17        int next;
     18        int from;
     19        int v;
     20        int c;
     21    }e[3000005];
     22   
     23 void add(int u,int v,int w,int c)
     24    {
     25        e[++cnt].next=head[u];
     26        head[u]=cnt;
     27        e[cnt].c=c;
     28        e[cnt].v=w;
     29        e[cnt].from=u;
     30        e[cnt].to=v;
     31    }   
     32 
     33 void insert(int u,int v,int w,int c)
     34    {
     35        add(u,v,w,c);
     36        add(v,u,0,-c);
     37    }
     38    
     39 bool spfa()
     40    {
     41         for (int i=0;i<=T;i++) dis[i]=inf;
     42         queue<int>que;
     43         que.push(0);
     44         inq[0]=1;
     45         dis[0]=0;
     46         while (!que.empty())
     47             {
     48                 int now=que.front();
     49                 que.pop();
     50                 for (int i=head[now];i;i=e[i].next)
     51                    if (e[i].v&&dis[e[i].to]>dis[now]+e[i].c)
     52                        {
     53                               dis[e[i].to]=dis[now]+e[i].c;
     54                               from[e[i].to]=i;
     55                               if (!inq[e[i].to])
     56                                   inq[e[i].to]=1,que.push(e[i].to);
     57                        }
     58                 inq[now]=0;       
     59             }
     60         if (dis[T]!=inf) return 1;
     61          else return 0;    
     62    }    
     63    
     64 void mcf()
     65    {
     66         int x=inf;
     67         for (int i=from[T];i;i=from[e[i].from])
     68                x=min(x,e[i].v);       
     69         for (int i=from[T];i;i=from[e[i].from])
     70             {
     71                 e[i].v-=x;
     72                 e[i^1].v+=x;
     73                 ans+=e[i].c*x;
     74             }
     75    }   
     76    
     77 int main()
     78    {
     79         scanf("%d%d",&n,&m);
     80         T=2*n+1;
     81         for (int i=1;i<=n;i++) scanf("%d",&a[i]);
     82         for (int i=1;i<=n;i++)
     83             {
     84                 insert(0,i,1,0);
     85                 insert(i+n,T,1,0);
     86                 insert(0,i+n,1,a[i]);
     87             }
     88         for (int i=1;i<=m;i++)
     89            {
     90               int u,v,w;
     91            scanf("%d%d%d",&u,&v,&w);
     92            if (u>v) swap(u,v);
     93            insert(u,v+n,1,w);     
     94            }
     95 
     96        while (spfa()) 
     97        mcf();    
     98        printf("%d
    ",ans);
     99        return 0;
    100    }
  • 相关阅读:
    -bash: fork: Cannot allocate memory 问题的处理
    Docker top 命令
    docker常见问题修复方法
    The Absolute Minimum Every Software Developer Absolutely, Positively Must Know About Unicode and Character Sets (No Excuses!)
    What's the difference between encoding and charset?
    hexcode of é î Latin-1 Supplement
    炉石Advanced rulebook
    炉石bug反馈
    Sidecar pattern
    SQL JOIN
  • 原文地址:https://www.cnblogs.com/grhyxzc/p/5191335.html
Copyright © 2011-2022 走看看