标签:acm
5 6 5 3 5 2 3 4 12 1 5 5 4 2 3 2 4 4 3 2 1
3
网络流: 点有权值费用,拆点建边。
#include <cstdio>
#include <queue>
#include <iostream>
#include <algorithm>
#include <cstring>
using namespace std;
typedef int MyType;
const int INF = 0x3F3F3F3F;
const int MAXN = 510;
const int MAXE = 100000 + 10;
struct Edge { int to, next; MyType cap; };
Edge es[MAXE];
int head[MAXN], cur[MAXN], level[MAXN], que[MAXN];
int n, m, src, des, cnt;
void add( int u, int v, MyType c ) {
es[cnt].to = v; es[cnt].cap = c; es[cnt].next = head[u]; head[u] = cnt++;
es[cnt].to = u; es[cnt].cap = 0; es[cnt].next = head[v]; head[v] = cnt++;
return ;
}
bool bfs() {
int mf, me;
memset( level, 0, sizeof( level ) );
mf = me = 0;
que[me++] = src;
level[src] = 1;
while( mf < me ) {
int u = que[mf++];
for( int i = head[u]; ~i; i = es[i].next ) {
int v = es[i].to;
if( level[v] == 0 && es[i].cap > 0 ) {
level[v] = level[u] + 1;
que[me++] = v;
}
}
}
return ( level[des] != 0 );
}
int dfs( int u, int f ) {
if( u == des || f == 0 ) return f;
int flow = 0;
for( int &i = cur[u]; ~i; i = es[i].next ) {
Edge &e = es[i];
if( e.cap > 0 && level[e.to] == level[u] + 1 ) {
int d = dfs( e.to, min( f, e.cap ) );
if( d > 0 ) {
e.cap -= d;
es[i ^ 1].cap += d;
flow += d;
f -= d;
if( f == 0 ) break;
} else level[e.to] = -1;
}
}
return flow;
}
MyType dinic() {
MyType ret = 0;
while( bfs() ) {
for( int i = 0; i <= 500; ++i ) {
cur[i] = head[i];
}
ret += dfs( src, INF );
}
return ret;
}
int main()
{
int a, b;
while(~scanf("%d%d%d%d", &n, &m, &src, &des))
{
memset(head, -1, sizeof head);
cnt = 0;
int tt;
des += 200;
for( int i = 1; i <= n; ++i ) {
scanf( "%d", &tt );
add( i, i + 200, tt );
}
for( int i = 1; i <= m; ++i ) {
scanf( "%d%d", &a, &b );
add( a + 200, b, INF );
add( b + 200, a, INF );
}
int ans = dinic();
printf( "%d\n", ans );
}
}版权声明:本文为博主原创文章,未经博主允许不得转载。
标签:acm
原文地址:http://blog.csdn.net/dojintian/article/details/47982469