zoukankan      html  css  js  c++  java
  • 网络流 E

    2012 If this is the end of the world how to do? I do not know how. But now scientists have found that some stars, who can live, but some people do not fit to live some of the planet. Now scientists want your help, is to determine what all of people can live in these planets. 

    InputMore set of test data, the beginning of each data is n (1 <= n <= 100000), m (1 <= m <= 10) n indicate there n people on the earth, m representatives m planet, planet and people labels are from 0. Here are n lines, each line represents a suitable living conditions of people, each row has m digits, the ith digits is 1, said that a person is fit to live in the ith-planet, or is 0 for this person is not suitable for living in the ith planet. 
    The last line has m digits, the ith digit ai indicates the ith planet can contain ai people most.. 
    0 <= ai <= 100000 
    OutputDetermine whether all people can live up to these stars 
    If you can output YES, otherwise output NO. 
    Sample Input

    1 1
    1
    1
    
    2 2
    1 0
    1 0
    1 1

    Sample Output

    YES
    NO





    题目大意:就是星球移民,不同的人对不同的星球适应情况不同,给你m个人n个星球和每个人对星球的适应情况,和每一个星球最大承载人数,让你求是否可以全部成功移民。

    这个题目是一个比较明显的网络流,但是dinic的复杂度是n*n*m,所以这个直接跑网络流肯定会超时。
    然后我就T了,虽然知道自己超时了,不过并没有想到怎么解决。
    然后搜题解,就看到了状态压缩。
    就是因为m=10,所以可以去考虑可能有些人对星球的适应情况是一样的,这个要用二进制的方式去转化
    怎么个状态压缩呢?

    就是因为可能有些人对星球的适应情况完全相同,所以就把人对星球的适应状况压缩成只含有01的数字。
    然后用map存储,这个之后就是建图了,
    建图你只要知道,你只需要利用map的数据建图就可以了,建好图map数组就没什么用了,所以你不需要一个对应关系。

    这个建图就看代码吧。

    这个卡cin

    #include <cstdio>
    #include <cstdlib>
    #include <cstring>
    #include <algorithm>
    #include <queue>
    #include <iostream>
    #include <vector>
    #include <map>
    #define inf 0x3f3f3f3f
    using namespace std;
    const int maxn = 1e5 + 100;
    typedef long long ll;
    int s, t, n, m;
    struct node
    {
        int from, to, cap, flow;
        node(int from=0,int to=0,int cap=0,int flow=0):from(from),to(to),cap(cap),flow(flow){}
    };
    vector<node>e;
    vector<int>G[maxn];
    void add(int u,int v,int c)
    {
        e.push_back(node(u, v, c, 0));
        e.push_back(node(v, u, 0, 0));
        int m = e.size();
        G[u].push_back(m - 2);
        G[v].push_back(m - 1);
    }
    int level[maxn], iter[maxn];
    void bfs(int s)
    {
        queue<int>que;
        que.push(s);
        memset(level, -1, sizeof(level));
        level[s] = 0;
        while(!que.empty())
        {
            int u = que.front(); que.pop();
            for(int i=0;i<G[u].size();i++)
            {
                node &now = e[G[u][i]];
                if(now.cap>now.flow&&level[now.to]<0)
                {
                    level[now.to] = level[u] + 1;
                    que.push(now.to);
                }
            }
        }
    }
    
    int dfs(int u,int v,int f)
    {
        if (u == v) return f;
        for(int &i=iter[u];i<G[u].size();i++)
        {
            node &now = e[G[u][i]];
            if(now.cap>now.flow&&level[now.to]>level[u])
            {
                int d = dfs(now.to, v, min(f, now.cap - now.flow));
                if(d>0)
                {
                    now.flow += d;
                    e[G[u][i] ^ 1].flow -= d;
                    return d;
                }
            }
        }
        return 0;
    }
    map<int, int>mp;
    int dinic()
    {
        int flow = 0;
        while(1)
        {
            bfs(s);
            if (level[t] < 0) return flow;
            for (int i = s; i <= t; i++) iter[i] = 0;
            int f;
            while ((f = dfs(s, t, inf)) > 0) flow += f;
        }
    }
    
    void init()
    {
        for (int i = 0; i <= n+m+5; i++) G[i].clear();
        e.clear();
        mp.clear();
    }
    int main()
    {
        while(scanf("%d%d",&n,&m)!=EOF)
        {
            init();
            s = 0;
            for(int i=1;i<=n;i++)
            {
                int ret = 0;
                for(int j=1;j<=m;j++)
                {
                    int x; scanf("%d", &x);
                    ret = ret + (x << j);
                }
                mp[ret]++;
            }
            int cnt = mp.size();
            int num = 0;
            map<int, int>::iterator p;
            for(p=mp.begin();p!=mp.end(); p++)
            {
                num++;
                for(int i=1;i<=m;i++)
                {
                    if ((p->first)&(1 << i))
                    {
                        add(num, cnt + i, p->second);
                    }
                }
                add(s, num, p->second);
            }
            t = num + m + 1;
            for(int i=1;i<=m;i++)
            {
                int x; scanf("%d", &x);
                add(num + i, t, x);
            }
            int ans = dinic();
            if (ans >= n) printf("YES
    ");
            else printf("NO
    ");
        }
        return 0;
    }







  • 相关阅读:
    Codeforces Round #454 Div. 2 A B C (暂时)
    Codeforces Round #453 Div. 2 A B C D (暂时)
    EOJ Monthly 2017.12 A B C D
    C++调用Matlab引擎 图像读写与处理 (知识+代码篇)
    Codeforces Round #449 Div. 2 A B C (暂时)
    AtCoder Regular Contest 077 E
    hdu 6218 Bridge 线段树 set
    hdu 2243 考研路茫茫——单词情结 AC自动机 矩阵幂次求和
    php配置php-fpm启动参数及配置详解
    PHP连接MySQL数据库的三种方式(mysql、mysqli、pdo)
  • 原文地址:https://www.cnblogs.com/EchoZQN/p/10746914.html
Copyright © 2011-2022 走看看