• BZOJ 3931: [CQOI2015]网络吞吐量( 最短路 + 最大流 )


    最短路 + 最大流 , 没什么好说的...

    因为long long WA 了两次....

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

    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    #include<queue>
    #include<vector>
    #include<iostream>
     
    #define rep( i , n ) for( int i = 0 ; i < n ; ++i )
    #define clr( x , c ) memset( x , c , sizeof( x ) )
     
    using namespace std;
     
    typedef long long ll;
     
    const ll INF = ( ll ) 1 << 60;
    const int maxn = 1000 + 5;
     
    struct edge {
    int to;
    ll cap;
    edge *next , *rev;
    };
     
    edge* pt;
    edge* head[ maxn ];
    edge EDGE[ maxn * maxn ];
     
    void init() {
    pt = EDGE;
    clr( head , 0 );
    }
     
    inline void add( int u , int v , ll d ) {
    pt -> to = v;
    pt -> cap = d;
    pt -> next = head[ u ];
    head[ u ] = pt++;
    }
     
    #define addEdge( u , v , d ) add( u , v , d ) , add( v , u , d )
     
    inline void add_edge( int u , int v , ll d ) {
    add( u , v , d );
    add( v , u , 0 );
    head[ u ] -> rev = head[ v ];
    head[ v ] -> rev = head[ u ];
    }
     
    ll d[ maxn ];
     
    void dijkstra( int n ) {
    rep( i , n ) d[ i ] = INF;
    d[ 0 ] = 0;
    priority_queue< pair< ll , int > > Q;
    Q.push( make_pair( 0 , 0 ) );
    while( ! Q.empty() ) {
    pair< ll , int > o = Q.top();
    Q.pop();
    int x = o.second;
    ll dist = o.first;
    if( dist != d[ x ] ) continue;
    for( edge* e = head[ x ] ; e ; e = e -> next ) if( d[ e -> to ] > d[ x ] + e -> cap ) {
    d[ e -> to ] = d[ x ] + e -> cap;
    Q.push( make_pair( d[ e -> to ] , e -> to ) );
    }
    }
    }
     
    edge *p[ maxn ] , *cur[ maxn ];
    int cnt[ maxn ] , h[ maxn ];
     
    ll maxFlow( int S , int T , int N ) {
    clr( cnt , 0 );
    cnt[ S ] = N;
    clr( h , 0 );
    ll flow = 0 , A = INF;
    int x = S;
    edge* e;
    while( h[ S ] < N ) {
    for( e = head[ x ] ; e ; e = e -> next )
       if( h[ e -> to ] + 1 == h[ x ] && e -> cap > 0 ) break;
       
    if( e ) {
    p[ e -> to ] = cur[ x ] = e;
    A = min( A , e -> cap );
    x = e -> to;
    if( x == T ) {
    while( x != S ) {
    p[ x ] -> cap -= A;
    p[ x ] -> rev -> cap += A;
    x = p[ x ] -> rev -> to;
    }
    flow += A;
    A = INF;
    }
    } else {
    if( ! --cnt[ h[ x ] ] ) break;
    h[ x ] = N;
    for( e = head[ x ] ; e ; e = e -> next ) if( e -> cap > 0 && h[ e -> to ] + 1 < h[ x ] ) {
    h[ x ] = h[ e -> to ] + 1;
    cur[ x ] = e;
    }
    cnt[ h[ x ] ]++;
    if( x != S ) x = p[ x ] -> rev -> to;
    }
    }
    return flow;
    }
     
    vector< int > U , V;
     
    int main() {
    int n , m;
    cin >> n >> m;
    init();
    while( m-- ) {
    int u , v , d;
    scanf( "%d%d%d" , &u , &v , &d );
    u-- , v--;
    addEdge( u , v , d );
    }
    dijkstra( n );
    U.clear();
    V.clear();
    rep( i , n )
    for( edge* e = head[ i ] ; e ; e = e -> next ) 
       if(d[ e -> to ] == d[ i ] + e -> cap )
           U.push_back( i + n ) , V.push_back( e -> to );
           
    init();
    rep( i , n ) {
    int v;
    scanf( "%d" , &v );
    i && i != n - 1 ? add_edge( i , i + n , v ) : add_edge( i , i + n , INF );
    }
    rep( i , V.size() )
       add_edge( U[ i ] , V[ i ] , INF );
       
    cout << maxFlow( 0 , n * 2 - 1 , n * 2 ) << " ";
    return 0;
    }

      

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

    3931: [CQOI2015]网络吞吐量

    Time Limit: 10 Sec  Memory Limit: 512 MB
    Submit: 585  Solved: 253
    [Submit][Status][Discuss]

    Description

     路由是指通过计算机网络把信息从源地址传输到目的地址的活动,也是计算机网络设计中的重点和难点。网络中实现路由转发的硬件设备称为路由器。为了使数据包最快的到达目的地,路由器需要选择最优的路径转发数据包。例如在常用的路由算法OSPF(开放式最短路径优先)中,路由器会使用经典的Dijkstra算法计算最短路径,然后尽量沿最短路径转发数据包。现在,若已知一个计算机网络中各路由器间的连接情况,以及各个路由器的最大吞吐量(即每秒能转发的数据包数量),假设所有数据包一定沿最短路径转发,试计算从路由器1到路由器n的网络的最大吞吐量。计算中忽略转发及传输的时间开销,不考虑链路的带宽限制,即认为数据包可以瞬间通过网络。路由器1到路由器n作为起点和终点,自身的吞吐量不用考虑,网络上也不存在将1和n直接相连的链路。

    Input

    输入文件第一行包含两个空格分开的正整数n和m,分别表示路由器数量和链路的数量。网络中的路由器使用1到n编号。接下来m行,每行包含三个空格分开的正整数a、b和d,表示从路由器a到路由器b存在一条距离为d的双向链路。 接下来n行,每行包含一个正整数c,分别给出每一个路由器的吞吐量。

    Output

    输出一个整数,为题目所求吞吐量。

    Sample Input

    7 10
    1 2 2
    1 5 2
    2 4 1
    2 3 3
    3 7 1
    4 5 4
    4 3 1
    4 6 1
    5 6 2
    6 7 1
    1
    100
    20
    50
    20
    60
    1

    Sample Output

    70

    HINT

     对于100%的数据,n≤500,m≤100000,d,c≤10^9

    Source

  • 相关阅读:
    Windowsforms 中对文件操作
    ADO.net增删改的使用
    ADO.net数据访问
    可空类型
    FineUI 页面跳转
    ASP.NET页面之间传递值的几种方式
    C# Find() 与 FindAll()方法的使用
    在Sql中将 varchar 值 '1,2,3,4,5,6' 转换成数据类型 int
    DataSet、DataTable、DataRow、DataColumn区别及使用实例
    C#中如何排除/过滤/清空/删除掉字符串数组中的空字符串
  • 原文地址:https://www.cnblogs.com/JSZX11556/p/4531903.html
Copyright © 2020-2023  润新知