hdu 3605

好吧,这道题我是T掉了,也不想去写二分的算法,写这个是记录下这个收获:

网络流中如果出现极端数据(一方很多,一方很少),那么可以考虑是否可以压缩,这道题就可以将人按照可以居住的星球的情况分类,然后就大大减少点和边。

T了的代码:

  1 #include <cstdio>
  2 #include <cstring>
  3 #include <queue>
  4 #include <vector>
  5 #define maxn 1100
  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 nn, int s, int d ) {
 20         n = nn;
 21         src = s;
 22         dst = d;
 23         for( int u=0; 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=0; 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( e.f && dep[e.v]==dep[e.u]+1 && (na=dfs(e.v,min(e.f,remain))) ) {
 58                 remain -= na;
 59                 past += na;
 60                 e.f -= na;
 61                 ve.f += na;
 62                 if( !remain ) 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 n, m;
 78 Dinic D;
 79 int bcnt[1<<10];
 80 
 81 int main() {
 82     while(1) {
 83         if( scanf( "%d%d", &n, &m )!=2 ) return 0;
 84         int tot = (1<<m)+m+2;
 85         D.init( tot, tot-1, tot );
 86         memset( bcnt, 0, sizeof(bcnt) );
 87         for( int i=1; i<=n; i++ ) {
 88             int cur = 0;
 89             for( int j=0; j<m; j++ ) {
 90                 int v;
 91                 scanf( "%d", &v );
 92                 cur |= v<<j;
 93             }
 94             bcnt[cur]++;
 95         }
 96         for( int b=0; b<(1<<m); b++ ) {
 97             D.add_edge( D.src, b, bcnt[b] );
 98             for( int j=0; j<m; j++ ) {
 99                 if( (b>>j)&1 )
100                     D.add_edge( b, (1<<m)+j+1, bcnt[b] );
101             }
102         }
103         for( int i=1; i<=m; i++ ) {
104             int v;
105             scanf( "%d", &v );
106             D.add_edge( (1<<m)+i, D.dst, v );
107         }
108         bool ok = D.maxflow()==n;
109         printf( "%s
", ok ? "YES" : "NO" );
110     }
111 }
View Code
原文地址:https://www.cnblogs.com/idy002/p/4320898.html