zoukankan      html  css  js  c++  java
  • HDU3605 Escape (最大流+缩点)

    2012如果这是世界末日怎么办?我不知道怎么做。但现在科学家们发现,有些恒星可以生存,但有些人却不适合生活在一些星球上。现在科学家们需要你的帮助,就是确定所有的人都能在这些星球上生活。

    输入

    多组测试数据,每个数据的开头是n(1<=n<=10万),m(1<=m<=10)n表示地球上有n个人,m代表m星球,行星和人的标签都是从0开始的。这里有n行,每行代表一个适合居住的人,每行有m个数字,第i个数字是1,表示一个人适合居住在第i个星球,或者是0,表示这个人不适合居住在第i个星球。

    最后一行有m个数字,第i个数字ai表示第i个星球最多能容纳ai人。。

    0<=ai<=100000

    输出

    决定是否所有的人都能不辜负这些明星

    如果可以输出YES,否则输出NO。

    点数很多,但是考虑到每个人只有1000种选择方案,可以缩点后跑网络流,时间复杂度是合理的。

    #include<bits/stdc++.h>
    using namespace std;
    typedef long long ll;
    const int maxn=2e5+100;
    const ll inf=1e18;
    int n,m;
    struct node {
        int u,v,nxt;
        ll w;
    }edge[maxn<<1];
    int head[maxn],tot;
    void addedge (int u,int v,ll w) {
        edge[tot].u=u;
        edge[tot].v=v;
        edge[tot].w=w;
        edge[tot].nxt=head[u];
        head[u]=tot++;
        
        edge[tot].u=v;
        edge[tot].v=u;
        edge[tot].w=0;
        edge[tot].nxt=head[v];
        head[v]=tot++;
    }
    
    ll dep[maxn],inq[maxn],cur[maxn],wjm,maxflow,s,t;
    bool bfs () {
        for (int i=0;i<=t;i++) {
            cur[i]=head[i];
            dep[i]=inf;
            inq[i]=0;
        }
        dep[s]=0;
        queue<int> q;
        q.push(s);
        while (q.size()) {
            int u=q.front();
            q.pop();
            inq[u]=0;
            for (int i=head[u];i!=-1;i=edge[i].nxt) {
                int v=edge[i].v;
                if (dep[v]>dep[u]+1&&edge[i].w) {
                    dep[v]=dep[u]+1;
                    if (inq[v]==0) {
                        q.push(v);
                        inq[v]=1;
                    }
                }
            }
        }
        if (dep[t]!=inf) return 1;
        return 0;
    }
    ll dfs (int u,ll flow) {
        ll increase=0;
        if (u==t) {
            wjm=1;
            maxflow+=flow;
            return flow;
        }
        ll used=0;
        for (int i=cur[u];i!=-1;i=edge[i].nxt) {
            cur[u]=i;
            int v=edge[i].v;
            if (edge[i].w&&dep[v]==dep[u]+1) {
                if (increase=dfs(v,min(flow-used,edge[i].w))) {
                    used+=increase;
                    edge[i].w-=increase;
                    edge[i^1].w+=increase;
                    if (used==flow) break;
                }
            } 
        }
        return used;
    }
    ll Dinic () {
        while (bfs()) {
            wjm=1;
            while (wjm==1) {
                wjm=0;
                dfs(s,inf);
            }
        }
        return maxflow;
    }
    int main () {
    //    源点为0
    //    1~n为人
    //    n+1~n+m为行星
    //    n+m+1为汇点 
    //    源点向每个人连一条容量为1的边
    //    每个人向可以居住的行星连一条容量为1的边
    //    每个行星向汇点连一条容量为a(i)的边 
        while (~scanf("%d%d",&n,&m)) {
            map<vector<int> ,int> mp;
            for (int i=1;i<=n;i++) {
                vector<int> tt;
                for (int j=1;j<=m;j++) {
                    int x;
                    scanf("%d",&x);
                    tt.push_back(x);
                }
                mp[tt]++;
            }
            s=0;
            t=mp.size()+m+1;
            for (int i=0;i<=t;i++) head[i]=-1;tot=0;wjm=0;maxflow=0;
            int cnt=0;
            for (auto it=mp.begin();it!=mp.end();it++) {
                cnt++;
                addedge(s,cnt,it->second);
                vector<int> tt=it->first;
                for (int i=0;i<tt.size();i++) if (tt[i]==1) addedge(cnt,mp.size()+i+1,it->second);
            }
            
            for (int i=1;i<=m;i++) {
                ll x;
                scanf("%lld",&x);
                addedge(mp.size()+i,t,x);
            } 
        //    printf("%lld
    ",Dinic());
            if (Dinic()==n)
                printf("YES
    ");
            else
                printf("NO
    ");
        }
    }
  • 相关阅读:
    查询数据库锁的SQL
    注解学习实例(模拟hibernate,table,column注解,拼装SQL)
    mongoDB学习笔记
    拼装SQL.例子
    MySQL实现类似Oracle序列的函数
    面试总结
    linux下常用命令
    PHP 中 flush() 与 ob_flush() 的区别
    PHP 使用共享内存的资料
    移动设备的web站开发和将web封转成移动端应用的一些资料
  • 原文地址:https://www.cnblogs.com/zhanglichen/p/14026207.html
Copyright © 2011-2022 走看看