zoukankan      html  css  js  c++  java
  • HDU3605 Escape(最大流判满流 + 状压)

    【题意】:

    有N个人,M个星球,给N*M矩阵,(i, j)为1代表i可以到j星球,0代表不能,问是否能把所有人转移走。

    【思路】:

    N的范围为1e6,如果让每个人与星球连边一定TLE,再根据矩阵每一行只有0,1可以进行状压,把相同状态idx的人合并到数组siz[idx],

    在扫描状态,与符合条件的星球连边。

    【建图】:

    超级源点sp -> idx  边权siz[idx]

    idx -> M  边权inf

    M -> 超级汇点tp  边权为容量

    #include <bits/stdc++.h>
    using namespace std;
    
    const int maxn = 1e5 + 5;
    const int maxm = 10 + 5;
    const int inf = 0x3f3f3f3f;
    int n, m, d[maxn+maxm], siz[maxn];
    int head[maxn+maxm], tot, maxflow;
    int sp, tp;
    struct edge{
        int to, w, next;
    } ed[(maxn*maxm+maxn+maxm)<<1];
    inline void init(){
        memset( head ,-1, sizeof(head) );
        memset( siz, 0, sizeof(siz) );
        tot = 1;
    }
    
    inline void add( int u, int v, int w ){
        ed[++tot].to = v; ed[tot].w = w; ed[tot].next = head[u]; head[u] = tot;
        ed[++tot].to = u; ed[tot].w = 0; ed[tot].next = head[v]; head[v] = tot;
    }
    
    inline bool bfs(){
        memset( d, 0, sizeof(d) );
        queue<int> q;
        d[sp] = 1;
        q.push(sp);
        while( !q.empty() ){
            int x = q.front();
            q.pop();
            for( int i=head[x]; i!=-1; i=ed[i].next ){
                int y = ed[i].to;
                if( ed[i].w && !d[y] ){
                    d[y] = d[x] + 1;
                    q.push(y);
                    if( y==tp ) return 1;
                }
            }
        }
        return 0;
    }
    
    inline int dfs( int x, int flow ){
        if( x==tp ) return flow;
        int res = flow, k;
        for( int i=head[x]; i!=-1 && res; i=ed[i].next ){
            int y = ed[i].to;
            if( ed[i].w && d[y]==d[x]+1 ){
                k = dfs( y, min( ed[i].w, res ) );
                if(!k) d[y] = 0;
                ed[i].w -= k;
                ed[i^1].w += k;
                res -= k;
            }
        }
        return flow-res;
    }
    
    inline void dinic(){
        int flow = maxflow = 0;
        while( bfs() )
            while( flow=dfs(sp, inf) ) maxflow += flow;
    }
    
    int main(){
        // freopen("in.txt", "r", stdin);
        while( ~scanf("%d%d", &n, &m) ){
            init();
            int l = inf, r = -inf;
            for( int i=1; i<=n; i++ ){
                int sum = 0;
                for( int j=1; j<=m; j++ ){
                    int tmp;
                    scanf("%d", &tmp);
                    sum <<= 1;
                    sum += tmp;
                }
                siz[sum] ++;
                l = min( l, sum ); r = max( r, sum );
            }
            sp = 0;
            tp = r+m+1;
            for( int i=1; i<=m; i++ ){
                int cont;
                scanf("%d", &cont);
                add( i+r, tp, cont );
            }
            for( int i=l; i<=r; i++ )
                if( siz[i] ){
                    int pos = 0;
                    while( pos<m ){
                        if( i&(1<<pos) ) add( i, m-pos+r, inf );
                        pos ++;
                    }
                    add( sp, i, siz[i] );
                }
            dinic();
            if( n<=maxflow ) puts("YES");
            else puts("NO");
        }
    
        return 0;
    }
  • 相关阅读:
    3.Appium运行时出现:Original error: Android devices must be of API level 17 or higher. Please change your device to Selendroid or upgrade Android on your device
    3.Python连接数据库PyMySQL
    2.Python输入pip命令出现Unknown or unsupported command 'install'问题解决
    2.Linux下安装Jenkins
    5.JMeter测试mysql数据库
    Android 4学习(7):用户界面
    Android 4学习(6):概述
    Android 4学习(5):概述
    Android 4学习(4):概述
    Android 4学习(3):概述
  • 原文地址:https://www.cnblogs.com/WAautomaton/p/11031958.html
Copyright © 2011-2022 走看看