POJ 3281 Dining( 网络流, Dinic 和ISAP )

来源:互联网 发布:qq飞车麦凯伦数据 编辑:程序博客网 时间:2024/06/06 21:57

Dinic:

#include<iostream>#include<cstdio>#include<cstring>#include<cmath>#include<algorithm>#include<set>#include<map>#include<queue>#include<vector>#include<cstdlib>#include<stack>using namespace std;#define inf 0x3f3f3f3f#define eps 1e-7#define LL long long#define ULL unsigned long long#define MP make_pair#define pb push_back#define ls ( i << 1 )#define rs ( ls | 1 )#define md ( ( ll[i] + rr[i] ) >> 1 )#define mxn 1020int q[mxn*mxn];struct edge {int u, v, cap, flow;edge() {}edge( int u, int v, int cap, int flow ): u( u ), v( v ), cap( cap ), flow( flow ) {}};struct Dinic {int n, m, s, t;vector<edge> edges;vector<int> G[mxn];bool vis[mxn];int d[mxn], cur[mxn];void add( int u, int v, int cap ) {edges.push_back( edge( u, v, cap, 0 ) );edges.push_back( edge( v, u, 0, 0 ) );m = edges.size();G[u].push_back( m - 2 );G[v].push_back( m - 1 );}bool bfs() {memset( vis, 0, sizeof( vis ) );int head = 0, tail = 1;q[0] = s;d[s] = 0, vis[s] = 1;while( head < tail ) {int x = q[head++];for( int i = 0; i < G[x].size(); ++i ) {edge &e = edges[G[x][i]];if( !vis[e.v] && e.cap > e.flow ) {vis[e.v] = 1;d[e.v] = d[x] + 1;q[tail++] = e.v;}}}return vis[t];}int dfs( int x, int a ) {if( x == t || a == 0 )return a;int flow = 0, f;for( int &i  = cur[x]; i < G[x].size(); ++i ) {edge &e = edges[G[x][i]];if( d[x] + 1 == d[e.v] && ( f = dfs( e.v, min( a, e.cap - e.flow ) ) ) > 0 ) {e.flow += f;edges[G[x][i]^1].flow -= f;flow += f;a -= f;if( a == 0 )break;}}return flow;}int calc( int s, int t ) {this -> s = s, this -> t = t;int flow = 0;while( bfs() ) {memset( cur, 0, sizeof( cur ) );flow += dfs( s, inf );}return flow;}}solver;int n, f, d;int main() {while( scanf( "%d%d%d", &n, &f, &d ) != EOF ) {for( int i = 1; i <= n; ++i ) {int n1, n2;scanf( "%d%d", &n1, &n2 );for( int j = 1; j <= n1; ++j ) {int u;scanf( "%d", &u );solver.add( u, f + i, 1 );}for( int j = 1; j <= n2; ++j ) {int u;scanf( "%d", &u );solver.add( f + n + i, f + 2 * n + u, 1 );}}for( int i = 1; i <= n; ++i )solver.add( f + i, f + n + i, 1 );int tot = f + 2 * n + d + 1;for( int i = 1; i <= f; ++i )solver.add( 0, i, 1 );for( int i = 1; i <= d; ++i )solver.add( f + 2 * n + i, tot, 1 );printf( "%d\n", solver.calc( 0, tot ) );}return 0;}



ISAP:

#include<iostream>#include<cstdio>#include<cstring>#include<cmath>#include<algorithm>#include<set>#include<map>#include<queue>#include<vector>#include<cstdlib>#include<stack>using namespace std;#define inf 0x3f3f3f3f#define eps 1e-7#define LL long long#define ULL unsigned long long#define MP make_pair#define pb push_back#define ls ( i << 1 )#define rs ( ls | 1 )#define md ( ( ll[i] + rr[i] ) >> 1 )#define mxn 1020int q[mxn*mxn];struct edge {int u, v, cap, flow;edge() {}edge( int u, int v, int cap, int flow ): u( u ), v( v ), cap( cap ), flow( flow ) {}};struct isap {int n, m, s, t;vector<edge> edges;vector<int> G[mxn];bool vis[mxn];int d[mxn], cur[mxn];int p[mxn], num[mxn];void add( int u, int v, int cap ) {edges.push_back( edge( u, v, cap, 0 ) );edges.push_back( edge( v, u, 0, 0 ) );m = edges.size();G[u].push_back( m - 2 );G[v].push_back( m - 1 );}int Aug() {int x = t, a = inf;while( x != s ) {edge &e = edges[p[x]];a = min( a, e.cap - e.flow );x = edges[p[x]].u;}x = t;while( x != s ) {edges[p[x]].flow += a;edges[p[x]^1].flow -= a;x = edges[p[x]].u;}return a;}bool bfs() {memset( vis, 0, sizeof( vis ) );int head = 0, tail = 1;q[0] = t;d[t] = 0, vis[t] = 1;while( head < tail ) {int x = q[head++];for( int i = 0; i < G[x].size(); ++i ) {edge &e = edges[G[x][i]];if( !vis[e.v] && e.cap == 0 ) {vis[e.v] = 1;d[e.v] = d[x] + 1;q[tail++] = e.v;}}}return vis[s];}int mf( int s, int t ) {this -> s = s, this -> t = t;int flow = 0;bfs();memset( num, 0, sizeof( num ) );for( int i = 0; i < n; ++i )num[d[i]] ++;int x = s;memset( cur, 0, sizeof( cur ) );while( d[s] < n ) {if( x == t )flow += Aug(), x = s;int ok = 0;for( int i = cur[x]; i < G[x].size(); ++i ) {edge &e = edges[G[x][i]];if( e.cap > e.flow && d[x] == d[e.v] + 1 ) {ok = 1;p[e.v] = G[x][i];cur[x] = i;x = e.v;break;}}if( !ok ) {int m = n - 1;for( int i = 0; i < G[x].size(); ++i ) {edge &e = edges[G[x][i]];if( e.cap > e.flow ) m = min( m, d[e.v] );}if( --num[d[x]] == 0 )break;num[d[x] = m + 1]++;cur[x] = 0;if( x != s )x = edges[p[x]].u;}}return flow;}}solver;int n, f, d;int main() {while( scanf( "%d%d%d", &n, &f, &d ) != EOF ) {for( int i = 1; i <= n; ++i ) {int n1, n2;scanf( "%d%d", &n1, &n2 );for( int j = 1; j <= n1; ++j ) {int u;scanf( "%d", &u );solver.add( u, f + i, 1 );}for( int j = 1; j <= n2; ++j ) {int u;scanf( "%d", &u );solver.add( f + n + i, f + 2 * n + u, 1 );}}for( int i = 1; i <= n; ++i )solver.add( f + i, f + n + i, 1 );int tot = f + 2 * n + d + 1;for( int i = 1; i <= f; ++i )solver.add( 0, i, 1 );for( int i = 1; i <= d; ++i )solver.add( f + 2 * n + i, tot, 1 );solver.n = tot + 1;printf( "%d\n", solver.mf( 0, tot ) );}return 0;}


0 0
原创粉丝点击