zoukankan      html  css  js  c++  java
  • LUOGU P1402 酒店之王 (网络流)

    解题思路

    应该比较显然得能看出这是个网络流,将$S$与房间连边,房间与人连边,人与菜连边,菜与汇点连边,边的流量均为1。但这样是错误的,因为有可能一个人跑过去2的流量,所以要将人拆点限流。

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<cstdlib>
    #include<cmath>
    #include<queue>
    
    using namespace std;
    const int MAXN = 505;
    const int MAXM = 50005;
    const int inf = 0x3f3f3f3f;
    
    inline int rd(){
        int x=0;char ch=getchar();
        while(!isdigit(ch)) ch=getchar();
        while(isdigit(ch))  {x=(x<<1)+(x<<3)+ch-'0';ch=getchar();}
        return x;
    }
    
    int n,p,q,head[MAXN],cnt=1,to[MAXM<<1],nxt[MAXM<<1],val[MAXM<<1];
    int ans,S,T=500,d[MAXN];
    queue<int> Q;
    
    inline void add(int bg,int ed,int w){
        to[++cnt]=ed,nxt[cnt]=head[bg],val[cnt]=w,head[bg]=cnt;
    }
    
    inline bool bfs(){
        while(Q.size()) Q.pop();
        memset(d,0,sizeof(d));d[S]=1;Q.push(S);
        while(Q.size()){
            int x=Q.front();Q.pop();
            for(register int i=head[x];i;i=nxt[i]){
                int u=to[i];
                if(!d[u] && val[i]){
                    d[u]=d[x]+1;
                    Q.push(u);
                    if(u==T) return true;
                }
            }
        }
        return false;
    }
    
    int dinic(int x,int flow){
        if(x==T) return flow;
        int res=flow,k;
        for(register int i=head[x];i && res;i=nxt[i]){
            int u=to[i];
            if(d[u]==d[x]+1 && val[i]){
                k=dinic(u,min(val[i],flow));
                if(!k) d[u]=0;
                val[i]-=k;val[i^1]+=k;res-=k;
            }
        }
        return flow-res;
    }
    
    int main(){
        n=rd(),p=rd(),q=rd();int x;
        for(int i=1;i<=p;i++) add(S,i,1),add(i,S,0);
        for(int i=1;i<=n;i++)
            for(int j=1;j<=p;j++){
                x=rd();if(!x) continue;
                add(j,i+p,1),add(i+p,j,0);
            }
        for(int i=1;i<=n;i++) add(i+p,i+p+n,1),add(i+p+n,i+p,0);
        for(int i=1;i<=n;i++)
            for(int j=1;j<=q;j++){
                x=rd();if(!x) continue;
                add(i+p+n,j+n*2+p,1),add(j+n*2+p,i+p+n,0);
            }
        for(int i=1;i<=q;i++) add(i+n*2+p,T,1),add(T,i+n*2+p,0);
        while(bfs()) ans+=dinic(S,inf);
        cout<<ans;
        return 0;
    }
    View Code
  • 相关阅读:
    [译] 关于CSS中的float和position
    【规范】前端编码规范——注释规范
    【规范】前端编码规范——jquery 规范
    【规范】前端编码规范——javascript 规范
    【规范】javascript 变量命名规则
    如何使用TestFlight进行Beta测试
    i o s 崩溃日志分析
    CocoaPods安装和使用教程
    iOS 程序切换后台
    iOS 百度地图获取当前地理位置
  • 原文地址:https://www.cnblogs.com/sdfzsyq/p/9784582.html
Copyright © 2011-2022 走看看