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
", lf );
144     }
145 }
View Code
原文地址:https://www.cnblogs.com/idy002/p/4321978.html