0w1

CFR 269 C. Flawed Flow ( Flow )

Problem - 269C - Codeforces
izrak の提出見て回答。

題意:
給你一張無向圖,邊有容量,要求定向,使得有最大流。源點 1,匯點 N。

制約:
2 ≤ N ≤ 2e5
N - 1 ≤ M ≤ 2e5
C[ i ] ≤ 1e4

解法:
初始時對所有邊的端點添上該邊的容量。
為了要滿足流量守恆,也就是進來的流等於出去的流,所以進行 BFS,每次取出來更新人家的必須是已經守恆的。顯然源點一直都是守恆的,所以可以做為起點。拿來更新人家的這個節點有多少向外的流量,就有相應多的流量可以幫助其他未平衡的節點平衡。
最後決定邊的方向的是平衡的時間順序,如果有條邊 ( u, v ),那麼 u -> v 若且唯若 u 平衡地比 v 早。
以下 code 可以用 BFS 寫,只是這樣很潮。
rewind( stdin ) 好潮。雖然會變慢很多。

複雜度:
O( M )

#include <bits/stdc++.h>
using namespace std;

const int MAXN = int( 2e5 );

int N, M;
int tot_flow[ MAXN ];
vector< pair< int, int > > G[ MAXN ];

signed main() {
  ios::sync_with_stdio( 0 );
  cin >> N >> M;
  for( int i = 0; i < M; ++i ) {
    int u, v, w;
    cin >> u >> v >> w;
    tot_flow[ u - 1 ] += w;
    tot_flow[ v - 1 ] += w;
    G[ u - 1 ].emplace_back( w, v - 1 );
    G[ v - 1 ].emplace_back( w, u - 1 );
  }
  tot_flow[ 0 ] = tot_flow[ N - 1 ] = -1;
  static int done[ MAXN ];
  static int in_flow[ MAXN ];
  int dptr = 0;
  done[ dptr++ ] = 0;
  for( int i = 0; i < dptr; ++i ) {
    for( int j = 0; j < G[ done[ i ] ].size(); ++j ) {
      in_flow[ G[ done[ i ] ][ j ].second ] += G[ done[ i ] ][ j ].first;
      if( in_flow[ G[ done[ i ] ][ j ].second ] * 2 == tot_flow[ G[ done[ i ] ][ j ].second ] ) {
        done[ dptr++ ] = G[ done[ i ] ][ j ].second;
      }
    }
  }
  done[ dptr++ ] = N - 1;
  static int ts[ MAXN ];
  for( int i = 0; i < N; ++i ) {
    ts[ done[ i ] ] = i;
  }
  rewind( stdin ); // rewinds the scanner pointer back to the beginning
  cin >> N >> M;
  for( int i = 0; i < M; ++i ) {
    int u, v, w;
    cin >> u >> v >> w;
    cout << "01"[ ts[ v - 1 ] < ts[ u - 1 ] ] << "\n";
  }
  return 0;
}