• bzoj1433: [ZJOI2009]假期的宿舍


    二分图匹配。

    每个点分为俩个点0和1,表示有床的人和要睡觉的人。跑最大流。

    图中所有边的流量均为1

    1.S向每个有床的人(0)连一条边。

    2.每个不回家的人和校外的人(1)向T连一条边。

    3.每个有床的人和自己连一条边(0->1)。

    4.每个认识的人连一条边(0->1).

    #include<cstdio>
    #include<algorithm>
    #include<cstring>
    using namespace std;
    const int maxn = 10000 + 10;
    const int maxm = 20000 + 10;
    const int inf = 0x3f3f3f3f;
    
    int g[maxn],v[maxm],next[maxm],f[maxm],eid;
    int id[maxn][2];
    int n,S,T,cnt,vid;
    int a[maxn],b[maxn];
    int dist[maxn],gap[maxn];
    
    void addedge(int a,int b,int F) {
        v[eid]=b; next[eid]=g[a]; f[eid]=F; g[a]=eid++;
        v[eid]=a; next[eid]=g[b]; f[eid]=0; g[b]=eid++;
    }
    
    void build() {
        memset(g,-1,sizeof(g)); eid=0; cnt=0; vid=0;
        scanf("%d",&n);
        for(int i=1;i<=n;i++) {
            id[i][0]=++vid;
            id[i][1]=++vid;
        }
        S=++vid; T=++vid;
        for(int i=1;i<=n;i++) {
            scanf("%d",&a[i]);
            if(a[i]) addedge(S,id[i][0],1);
        }
        
        for(int i=1;i<=n;i++) {
            scanf("%d",&b[i]);
            if(!a[i] || !b[i]) {
                cnt++;
                addedge(id[i][1],T,1);
            }
        }
        
        for(int i=1,t;i<=n;i++) 
            for(int j=1;j<=n;j++) {
                scanf("%d",&t);
                if(a[i] && t) addedge(id[i][0],id[j][1],1);
                if(a[i] || i==j) addedge(id[i][0],id[i][1],1);
            }                        
    }
    
    int ISAP(int u,int flow) {
        if(u==T) return flow;
        int cur=0,aug,mindist=vid;
        
        for(int i=g[u];~i;i=next[i]) if(f[i] && dist[v[i]]+1==dist[u]) {
            aug=ISAP(v[i],min(flow-cur,f[i]));
            f[i]-=aug;
            f[i^1]+=aug;
            cur+=aug;
            if(cur==flow || dist[S] >= vid) return cur;    
        }
        
        if(cur==0) {
            if(!--gap[dist[u]]) {
                dist[S]=vid;
                return cur;
            }
            for(int i=g[u];~i;i=next[i]) if(f[i]) 
                mindist=min(mindist,dist[v[i]]);
            ++gap[dist[u]=mindist+1];
        }
        return cur;
    }
    
    void solve() {
        int res=0;
        memset(dist,0,sizeof(dist));
        gap[0]=vid;
        while(dist[S]<vid) res+=ISAP(S,inf);
        printf(res==cnt?"^_^
    ":"T_T
    ");
    }
    
    int main() {
        int T;
        scanf("%d",&T);
        while(T--) {
            build();
            solve();    
        }
        return 0;    
    }
  • 相关阅读:
    使用JQuery实现延迟加载UserControl
    VisualStudio中的列选择
    SQL SERVER 2008 CTE生成结点的FullPath
    woocommerce独立站建站
    Java NIO使用及原理分析(二)
    java.io学习总结 转载
    java io与装饰器模式
    函数式思维: 不变性
    函数式思维: 运用函数式思维,第2 部分
    maven添加非官方jar包到本地库(maven: install an external jar into local maven repository)
  • 原文地址:https://www.cnblogs.com/invoid/p/5590747.html
Copyright © 2020-2023  润新知