hdu 3081
二分答案,网络流是否满流判断合法性。
1 #include <cstdio> 2 #include <cstring> 3 #include <queue> 4 #include <vector> 5 #define maxn 210 6 #define oo 0x3f3f3f3f 7 using namespace std; 8 9 struct Edge { 10 int u, v, f; 11 Edge( int u, int v, int f ):u(u),v(v),f(f){} 12 }; 13 struct Dinic { 14 int n, src, dst; 15 vector<Edge> edge; 16 vector<int> g[maxn]; 17 int dep[maxn], cur[maxn]; 18 19 void init( int n, int src, int dst ) { 20 this->n = n; 21 this->src = src; 22 this->dst = dst; 23 for( int u=1; u<=n; u++ ) 24 g[u].clear(); 25 edge.clear(); 26 } 27 void add_edge( int u, int v, int f ) { 28 g[u].push_back( edge.size() ); 29 edge.push_back( Edge(u,v,f) ); 30 g[v].push_back( edge.size() ); 31 edge.push_back( Edge(v,u,0) ); 32 } 33 bool bfs() { 34 queue<int> qu; 35 memset( dep, 0, sizeof(dep) ); 36 qu.push( src ); 37 dep[src] = 1; 38 while( !qu.empty() ) { 39 int u=qu.front(); 40 qu.pop(); 41 for( int &t=cur[u]; t<g[u].size(); t++ ) { 42 Edge &e = edge[g[u][t]]; 43 if( e.f && !dep[e.v] ) { 44 dep[e.v] = dep[e.u]+1; 45 qu.push( e.v ); 46 } 47 } 48 } 49 return dep[dst]; 50 } 51 int dfs( int u, int a ) { 52 if( u==dst || a==0 ) return a; 53 int remain=a, past=0, na; 54 for( int &t=cur[u]; t<g[u].size(); t++ ) { 55 Edge &e = edge[g[u][t]]; 56 Edge &ve = edge[g[u][t]^1]; 57 if( dep[e.v]==dep[e.u]+1 && (na=dfs(e.v,min(remain,e.f))) ) { 58 remain -= na; 59 past += na; 60 e.f -= na; 61 ve.f += na; 62 if( remain==0 ) break; 63 } 64 } 65 return past; 66 } 67 int maxflow() { 68 int flow = 0; 69 while( bfs() ) { 70 memset( cur, 0, sizeof(cur) ); 71 flow += dfs(src,oo); 72 } 73 return flow; 74 } 75 }; 76 77 int fa[maxn]; 78 79 void init( int n ) { 80 for( int i=1; i<=n; i++ ) 81 fa[i] = i; 82 } 83 int find( int a ) { 84 return a==fa[a] ? a : fa[a]=find(fa[a]); 85 } 86 void unon( int a, int b ) { 87 a = find(a); 88 b = find(b); 89 fa[a] = b; 90 } 91 92 int n, m, f; 93 bool cnnt[110][110]; 94 int cnt[110]; 95 vector<int> stk; 96 Dinic D; 97 98 bool ok( int mid ) { 99 D.init( n+n+2, n+n+1, n+n+2 ); 100 for( int u=1; u<=n; u++ ) { 101 if( fa[u]!=u ) continue; 102 D.add_edge( D.src, u, mid*cnt[u] ); 103 for( int v=1; v<=n; v++ ) { 104 if( !cnnt[u][v] ) continue; 105 D.add_edge( u, v+n, cnt[u] ); 106 } 107 } 108 for( int v=1; v<=n; v++ ) 109 D.add_edge( v+n, D.dst, mid ); 110 return D.maxflow()==mid*n; 111 } 112 int main() { 113 int T; 114 scanf( "%d", &T ); 115 while( T-- ) { 116 scanf( "%d%d%d", &n, &m, &f ); 117 memset( cnnt, 0, sizeof(cnnt) ); 118 for( int i=1,u,v; i<=m; i++ ) { 119 scanf( "%d%d", &u, &v ); 120 cnnt[u][v] = 1; 121 } 122 init(n); 123 for( int i=1,u,v; i<=f; i++ ) { 124 scanf( "%d%d", &u, &v ); 125 unon(u,v); 126 } 127 memset( cnt, 0, sizeof(cnt) ); 128 for( int i=1; i<=n; i++ ) { 129 int r = find(i); 130 cnt[r]++; 131 for( int j=1; j<=n; j++ ) 132 cnnt[r][j] |= cnnt[i][j]; 133 } 134 stk.clear(); 135 for( int i=1; i<=n; i++ ) 136 if( fa[i]==i ) stk.push_back(i); 137 int lf=0, rg=n; 138 while( lf<rg ) { 139 int mid = (lf+rg+1)>>1; 140 if( ok(mid) ) lf=mid; 141 else rg=mid-1; 142 } 143 printf( "%d\n", lf ); 144 } 145 }