• 【洛谷P1402】酒店之王


    如题,一眼看上去是这样的。

    如果只看人和房间,或者只看人和菜,那么这题就是一个sb的二分图最大匹配,随便跑就好了。

    那么怎么同时满足呢?

    两个图都建,然后两个图的人向自己连一条长度=1的边,用来限制流量防止这个人精分

    #include<bits/stdc++.h>
    #define inf 10000010
    #define N 1101
    using namespace std;
    int s,t,n,m,q,p,ans,d;
    struct Edge{int u,v,next,f;}G[1010000];
    int tot=0,head[N<<2];
    inline void addedge(int u,int v,int f){
        G[tot].u=u;G[tot].v=v;G[tot].f=f;G[tot].next=head[u];head[u]=tot++;
        G[tot].u=v;G[tot].v=u;G[tot].f=0;G[tot].next=head[v];head[v]=tot++;
    }
    int level[N<<2];
    inline bool bfs(int s,int t){
        memset(level,0,sizeof(level));
        queue<int>q;q.push(s);level[s]=1;
        while(!q.empty()){//puts("!!!");
            int u=q.front();q.pop();
            if(u==t)return 1;
            for(int i=head[u];~i;i=G[i].next){
                int v=G[i].v,f=G[i].f;
                if(f&&!level[v])level[v]=level[u]+1,q.push(v);
            }
        } 
        return 0;
    }
    int dfs(int u,int maxf,int t){
        if(u==t)return maxf;int rat=0;
        for(int i=head[u];~i&&rat<maxf;i=G[i].next){
            int v=G[i].v,f=G[i].f;
            if(f&&level[v]==level[u]+1){
                f=dfs(v,min(maxf-rat,f),t);
                rat+=f;G[i].f-=f;G[i^1].f+=f;
            }
        }
        if(!rat)level[u]=inf;
        return rat;
    }
    inline int dinic(int s,int t){
        int ans=0;
        while(bfs(s,t))ans+=dfs(s,inf,t);
        return ans;
    }
    inline int read(){
        int f=1,x=0;char ch;
        do{ch=getchar();if(ch=='-')f=-1;}while(ch<'0'||ch>'9');
        do{x=x*10+ch-'0';ch=getchar();}while(ch>='0'&&ch<='9');
        return f*x;
    }
    int main(){
        n=read();p=read();q=read();
        memset(head,-1,sizeof(head));s=0;t=n+n+p+q+1;
        for(int i=1;i<=n;i++){
            addedge(i+p,i+p+n,1);
            for(int j=1;j<=p;j++){
                if(i==1)addedge(0,j,1);
                int u=read();
                if(u)addedge(j,i+p,1);
            }
        }
        for(int i=1;i<=n;i++){
            for(int j=1;j<=q;j++){
                if(i==1)addedge(j+p+n+n,t,1);
                int u=read();
                if(u)addedge(i+p+n,j+p+n+n,1);
            }
        }
        int ans=dinic(s,t);
        printf("%d
    ",ans);
        return 0;
    }
  • 相关阅读:
    【转】 Android代码混淆之混淆规则
    【转】java虚拟机机制总结
    【转】图解 HTTP协议/IIS 原理及ASP.NET运行机制浅析
    【转】Android 消息机制
    Android-eclipse-NDK&JNI
    【转】大型网站系统架构的演化
    【转】Android开发必知--WebView加载html5实现炫酷引导页面
    【转】Java虚拟机详解----GC算法和种类
    网页中缩略图的意义
    网页开关灯效果
  • 原文地址:https://www.cnblogs.com/zcysky/p/6858679.html
Copyright © 2020-2023  润新知