写了两个版本的dinic,一个是递归版本的,一个是非递归的,防止考场上爆炸。
#include <bits/stdc++.h>
#define rep( i , l , r ) for( int i = (l) ; i <= (r) ; ++i )
#define per( i , r , l ) for( int i = (r) ; i >= (l) ; --i )
#define erep( i , u ) for( int i = head[(u)] ; ~i ; i = e[i].nxt )
using namespace std;
const int INF = 0x3f3f3f3f;
const int maxn = 11111;
const int maxm = 222222;
int dep[maxn] , head[maxn] , _t;
struct edge{
int u , v , nxt;
int c;
} e[maxm];
inline void addedge( int u , int v , int c ){
e[_t].u = u , e[_t].v = v , e[_t].nxt = head[u] , e[_t].c = c , head[u] = _t++;
e[_t].u = v , e[_t].v = u , e[_t].nxt = head[v] , e[_t].c = 0 , head[v] = _t++;
}
int N , M , S , T;
int cur[maxn];
bool bfs(){ // 给图分层
for( int i = 0 ; i <= N ; ++i ){
dep[i] = INF;
cur[i] = head[i];
}
dep[S] = 0;
queue<int> q;
q.push( S );
while( !q.empty() ){
int u = q.front(); q.pop();
erep( i , u ){
int v = e[i].v;
if( dep[v] > dep[u] + 1 && e[i].c > 0 ){
dep[v] = dep[u] + 1;
q.push( v );
if( v == T ) return 1;
}
}
}
return 0;
}
inline int _min( int a , int b ){
return a > b ? b : a;
}
// recursive version
//bool vis = 0;
//int max_flow = 0;
//int dfs( int u , int flow ){
// int cur_low = 0;
// if( u == T ){
// vis = 1;
// max_flow += flow; // 直接累加
// return flow;
// }
// int used = 0; // 当前已经使用的流量
// for( int i = cur[u] ; ~i ; cur[u] = i = e[i].nxt ){
// int v = e[i].v;
// if( e[i].c > 0 && dep[v] == dep[u] + 1 ){
// if( cur_low = dfs( v , _min( flow - used , e[i].c ) ) ){
// used += cur_low;
// e[i].c -= cur_low;
// e[i^1].c += cur_low;
// if( used == flow ) break; // 流量使用完说明这个点无法增广了
// }
// }
// }
// return used; // 返回已经使用的流量
//}
//int Dinic(){
// while( bfs() ){
// for( vis = 1 ; vis ; ){
// vis = 0;
// dfs( S , INF );
// }
// }
// return max_flow;
//}
// non-recursive version
int Dinic(){
int res = 0;
int top = 0;
int stack[maxn];
while( bfs() ){
int u = S;
top = 0;
for(;;){
if( u == T ){
int mi = INF , loc;
for( int i = 0 ; i < top ; ++i )
if( mi > e[stack[i]].c ){
loc = i;
mi = e[stack[i]].c;
}
for( int i = 0 ; i < top ; ++i ){
e[stack[i]].c -= mi;
e[stack[i]^1].c += mi;
}
res += mi;
top = loc;
u = e[stack[top]].u;
}
for( int i = cur[u] ; ~i ; cur[u] = i = e[i].nxt )
if( e[i].c > 0 && dep[e[i].v] == dep[u] + 1 ){
break;
}
if( cur[u] != -1 ){
stack[top++] = cur[u];
u = e[cur[u]].v;
}else{
if( top == 0 ) break;
dep[u] = INF;
u = e[stack[--top]].u;
}
}
}
return res;
}
int main(){
ios::sync_with_stdio(false);
cin >> N >> M >> S >> T;
memset( head , 0xff , sizeof head );
int u , v , c;
for( int i = 1 ; i <= M ; ++i ){
cin >> u >> v >> c;
addedge( u , v , c );
}
cout << Dinic() << endl;
return 0;
}
#include <bits/stdc++.h>
#define rep( i , l , r ) for( int i = (l) ; i <= (r) ; ++i )
#define per( i , r , l ) for( int i = (r) ; i >= (l) ; --i )
#define erep( i , u ) for( int i = head[(u)] ; i ; i = e[i].nxt )
#define PII pair<int , int>
#define MP make_pair
#define FR q.front()
using namespace std;
const int maxn = 100000 + 5;
struct edge{
int v , c , w , nxt;
} e[maxn * 2];
int head[maxn] , _t = 1;
inline void ins( int u , int v , int c , int w ){
e[++_t].v = v , e[_t].w = w , e[_t].c = c , e[_t].nxt = head[u] , head[u] = _t;
e[++_t].v = u , e[_t].w = -w , e[_t].c = 0 , e[_t].nxt = head[v] , head[v] = _t;
}
int S , T;
queue<int> q;
bool inq[maxn];
int dis[maxn];
int prev[maxn] , pree[maxn];
const int INF = 0x7f7f7f7f;
bool spfa(){
while( !q.empty() ) q.pop();
memset( dis , 0x7f , sizeof dis );
memset( inq , 0 , sizeof inq );
q.push( S ) ; dis[S] = 0 , inq[S] = 1;
while( !q.empty() ){
int u = FR; q.pop();
erep( i , u ){
int v = e[i].v;
if( e[i].c > 0 && dis[u] + e[i].w < dis[v] ){
dis[v] = dis[u] + e[i].w;
prev[v] = u , pree[v] = i;
if( !inq[v] ){ q.push(v); inq[v] = 1; }
}
}
inq[u] = 0;
}
if( dis[T] < INF ) return 1;
else return 0;
}
inline void cmin( int &a , const int &b ){
a = a < b ? a : b;
}
PII augment(){
int u = T , d = INF ;
for( ; u != S ; u = prev[u] ) cmin( d , e[pree[u]].c );
u = T;
for( ; u != S ; u = prev[u] ) e[pree[u]].c -= d , e[pree[u] ^ 1].c += d;
return MP( dis[T] * d , d );
}
PII MCF(){
int cur = 0 , ans = INF , res = 0;
while( spfa() ){
PII t = augment();
cur += t.first , res += t.second;
}
return make_pair( res , cur );
}
int main(){
int N , M , u , v , c , w;
scanf("%d %d %d %d" , &N , &M , &S , &T);
rep( i , 1 , M ){
scanf("%d %d %d %d" , &u , &v , &c , &w);
ins( u , v , c , w );
}
PII ans = MCF();
cout << ans.first << " " << ans.second << endl;
return 0;
}