经典网络流
sap:
#include <iostream>
#include <cstring>
#include <queue>
#include <stack>
using namespace std ;
const int MAXN = 500 ;
const int MAXM = 25000 ;
const int INF = 9999999 ;
int map[MAXN+10][MAXN+10] ;
int dis[MAXN+10] , gap[MAXN+10] , pre[MAXN+10] ;
int M , N ;
int sap( int , int , int ) ;
void bfs( int , int , int ) ;
int main()
{
int i , j , s , e , w ;
while( cin >> M >> N )
{
memset( map , 0 , sizeof( map ) ) ;
for( i = 0 ; i < M ; i ++ )
{
cin >> s >> e >> w ;
map[s][e] += w ;
}
cout << sap( 1 , N , N ) << endl ;
}
return 0 ;
}
int sap( int start , int end , int num )
{
int ans = 0 , pos , temp ;
int i , j ;
memset( pre , -1 , sizeof( pre ) ) ;
pos = start ;
bfs( start , end , num ) ;
while( dis[start] < num )
{
temp = -1 ;
for( i = 0 ; i <= num ; i ++ )
if( map[pos][i] > 0 && dis[pos] == dis[i] + 1 )
{
temp = i ;
break ;
}
if( temp >= 0 )
{
pre[temp] = pos ;
pos = temp ;
if( pos == end )
{
int flow = INF ;
for( i = end ; i != start ; i = pre[i] )
flow = min( flow , map[pre[i]][i] ) ;
for( i = end ; i != start ; i = pre[i] )
map[pre[i]][i] -= flow , map[i][pre[i]] += flow ;
ans += flow ;
pos = start ;
}
}
else
{
int Min = INF ;
for( i = 0 ; i <= num ; i ++ )
if( map[pos][i] )
Min = min( Min , dis[i] + 1 ) ;
if( Min == INF ) Min = num ;
gap[Min] ++ ;
gap[dis[pos]] -- ;
if( !gap[dis[pos]] )
return ans ;
dis[pos] = Min ;
if( pos != start )
pos = pre[pos] ;
}
}
return ans ;
}
void bfs( int start , int end , int num )
{
int i , j , temp ;
queue <int> q ;
memset( gap , 0 , sizeof( gap ) ) ;
memset( dis , INF , sizeof( dis ) ) ;
gap[0] = 1 ;
dis[end] = 0 ;
q.push( end ) ;
while( !q.empty() )
{
temp = q.front() ;
q.pop() ;
for( i = 0 ; i <= num ; i ++ )
{
if( map[i][temp] > 0 && dis[i] >= N )
{
dis[i] = dis[temp] + 1 ;
q.push( i ) ;
gap[dis[i]] ++ ;
}
}
}
return ;
}
EK:
#include <iostream>
#include <cstring>
#include <queue>
using namespace std ;
int map[201][201] , p[201] ;
int Edmonds_Karp( int , int , int ) ;
int bfs( int , int , int ) ;
int main()
{
int M , N , start , end , w ;
while( cin >> M >> N ){
memset( map , 0 , sizeof( map ) ) ;
memset( p , -1 , sizeof( p ) ) ;
while( M -- )
{
cin >> start >> end >> w ;
map[start][end] += w ;
}
cout << Edmonds_Karp( 1 , N , N ) << endl ;
}
return 0 ;
}
int Edmonds_Karp( int start , int end , int num )
{
int i , j , sum = 0 ;
int path ;
while( 1 )
{
path = bfs( start , end , num ) ;
if( path < 0 ) break ;
sum += path ;
i = end ;
while( p[i] != -1 )
{
map[p[i]][i] -= path ;
map[i][p[i]] += path ;
i = p[i] ;
}
memset( p , -1 , sizeof( p ) ) ;
}
return sum ;
}
int bfs( int start , int end , int num )
{
int path = 999999 ;
int temp , i , flag = 0 ;
bool vis[201] ;
memset( vis , 0 , sizeof( vis ) ) ;
queue < int > q ;
q.push( start ) ;
vis[start] = 1 ;
while( ! q.empty() )
{
temp = q.front() ;
if( temp == end ) { flag = 1 ; break ; }
q.pop() ;
for( i = 1 ; i <= num ; i ++ ) // 这里设1是第一个点
{
if( !vis[i] && map[temp][i] > 0 )
{
p[i] = temp ;
q.push( i ) ;
vis[i] = 1 ;
}
}
}
i = end ;
while( p[i] != -1 ){
if( map[p[i]][i] < path )
path = map[p[i]][i] ;
i = p[i] ;
}
if( flag == 0 ) return -1 ;
else return path ;
}
dinic:
#include <iostream>
#include <cstring>
#include <queue>
using namespace std ;
const int INF = 99999999 ;
const int MAXN = 4005 ;
const int MAXM = MAXN * 100 ;
struct type
{
int end , next , w ;
} ;
type edge[MAXM] ;
int head[MAXN] , Count , level[MAXN] ;
void addedge( int start , int end , int w )
{
edge[Count].end = end ;
edge[Count].w = w ;
edge[Count].next = head[start] ;
head[start] = Count ++ ;
edge[Count].end = start ;
edge[Count].w = 0 ;
edge[Count].next = head[end] ;
head[end] = Count ++ ;
}
bool dinic_bfs( int start , int end )
{
queue < int > q ;
memset( level , 0 , sizeof( level ) ) ;
q.push( start ) ;
level[start] = 1 ;
while( ! q.empty() )
{
int temp = q.front() ;
q.pop() ;
for( int i = head[temp] ; i != -1 ; i = edge[i].next )
if( ! level[edge[i].end] && edge[i].w )
{
level[edge[i].end] = level[temp] + 1 ;
q.push( edge[i].end ) ;
}
}
return level[end] != 0 ;
}
int dinic_dfs( int start , int end , int cp )
{
int temp = cp ;
if( start == end ) return cp ;
for( int i = head[start] ; i != -1 && temp ; i = edge[i].next )
if( level[edge[i].end] == level[start] + 1 && edge[i].w ){
int t = dinic_dfs( edge[i].end , end , min( temp , edge[i].w ) ) ;
edge[i].w -= t ;
edge[i^1].w += t ;
temp -= t ;
}
return cp - temp ;
}
int dinic( int start , int end )
{
int sum , path ;
sum = path = 0 ;
while( dinic_bfs( start , end ) ){
while( path = dinic_dfs( start , end , INF ) )
sum += path ;
}
return sum ;
}
int main()
{
int m , n , start , end , w ;
while( cin >> m >> n )
{
memset( head , -1 , sizeof( head ) ) ;
Count = 0 ;
while( m -- ){
cin >> start >> end >> w ;
addedge( start , end , w ) ;
}
cout << dinic( 1 , n ) << endl ;
}
return 0 ;
}