您的位置:首页 > 理论基础 > 计算机网络

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

2015-05-26 22:02 316 查看


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

因为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 ) << "\n"; 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

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: