zoukankan      html  css  js  c++  java
  • BZOJ 1927: [Sdoi2010]星际竞速(最小费用最大流)

    拆点,费用流... 

    -----------------------------------------------------------------------------

    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    #include<iostream>
    #include<queue>
     
    #define rep( i, n ) for( int i = 0; i < n; ++i )
    #define Rep( i, n ) for( int i = 1; i <= n; ++i )
    #define clr( x, c ) memset( x, c, sizeof( x ) )
     
    using namespace std; 
     
    const int INF = 0x3f3f3f3f;
    const int maxn = 1600 + 5;
     
    struct edge {
    int to, cap, cost;
    edge *next, *rev;
    };
     
    edge* pt;
    edge* head[ maxn ];
    edge EDGE[40000];
     
    void init() {
    pt = EDGE;
    clr( head, 0 );
    }
     
    inline void add( int u, int v, int d, int w ) {
    pt -> to = v;
    pt -> cap = d;
    pt -> cost = w;
    pt -> next = head[ u ];
    head[ u ] = pt++;
    }
     
    inline void add_edge( int u, int v, int d, int w ) {
    add( u, v, d, w );
    add( v, u, 0, -w );
    head[ u ] -> rev = head[ v ];
    head[ v ] -> rev = head[ u ];
    }
     
    edge* p[ maxn ];
    int d[ maxn ], a[ maxn ];
    bool inQ[ maxn ];
     
    int minCost( int S, int T ) {
    int cost = 0;
    for( ; ; ) {
    clr( d, INF );
    clr( inQ, 0 );
    queue< int > Q;
    d[ S ] = 0, a[ S ] = INF, Q.push( S );
    while( ! Q.empty() ) {
    int x = Q.front();
    Q.pop();
    inQ[ x ] = 0;
    for( edge* e = head[ x ]; e; e = e -> next) 
       if(d[ e -> to ] > d[ x ] + e -> cost && e -> cap > 0) {
       
       int to = e -> to;
       
       p[ to ] = e;
       a[ to ] = min( a[ x ], e -> cap );
       d[ to ] = d[ x ] + e -> cost;
       
       if( ! inQ[ to ] )
           Q.push( to ), inQ[ to ] = 1;
    }
    }
    if(d[ T ] == INF) break;
    cost += d[ T ] * a[ T ];
    int x = T;
    while( x != S) {
    p[ x ] -> cap -= a[ T ];
    p[ x ] -> rev -> cap += a[ T ];
    x = p[ x ] -> rev -> to;
    }
    }
    return cost;
    }
    int main() {
    init();
    int n, m;
    cin >> n >> m;
    int s = 0, t = n * 2 + 1;
    Rep( i, n ) {
    int x;
    scanf( "%d", &x );
    add_edge( s, i + n, 1, x );
    add_edge( i + n, t, 1, 0 );
    add_edge( s, i, 1, 0 );
    }
    while( m-- ) {
    int u, v, d;
    scanf( "%d%d%d", &u, &v, &d );
    if( u > v ) swap( u, v );
    add_edge( u, v + n, 1, d );
    }
    cout << minCost( s, t ) << " ";
    return 0;
    }
     

    ----------------------------------------------------------------------------- 

    1927: [Sdoi2010]星际竞速

    Time Limit: 20 Sec  Memory Limit: 259 MB
    Submit: 1401  Solved: 840
    [Submit][Status][Discuss]

    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更优,但我们却不能那样做,因为
    那会导致超能电驴爆炸。 

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

    Source

  • 相关阅读:
    设计模式的分类
    设计模式工厂方法模式
    设计模式的定义
    帕斯卡命名法
    C#编写程序找一找一个二维数组中的鞍点(即该位置上的元素值在行中最大,在该 列上最小。有可能数组没有鞍点)。要求:1.二维数组的大小、数组元素的值在运行时输入;2.程序有友好的提示信息。
    设计模式抽象工厂模式
    设计模式七大原则
    理解C#中的接口
    Linux下如何查看CPU信息, 包括位数和多核信息
    关于结构体内存对齐
  • 原文地址:https://www.cnblogs.com/JSZX11556/p/4524726.html
Copyright © 2011-2022 走看看