P2055 [ZJOI2009] holiday quarters [bipartite graph matching]

Title Description

School holidays · · · · · · some students went home, but some students there before to visit a good friend, so accommodation is a problem.

For example, A and B are school students, A to go home, and C of view B, C and A do not know. We assume that each person can only sleep and their own direct knowledge of the human bed. So one solution is to sleep B and C A bed to sleep in the bed B. The reality can be very complex, and some people may know a lot of students do not necessarily know each other between students.

A total of n people we know, and know where everyone is not our students, our students know whether or not each home. Q. Is there a program so that all of our students do not go home and look at their other people have a place to live.

Resolve

Look, oh roar, bipartite graph maximum matching did not have to run.

Obviously stay in school did not walk people (including students and outsiders) to be matched with a bed, and students (including the walk) have beds. Then we can put all the people in the school as a part node left, the right part of the all bed as a node, if the maximum matching \ (= \) the number of students stay in school, the program feasible.

Hungary or the maximum flow, maximum flow I write, practice your hand.

Reference Code

#include<cstdio>
#include<iostream>
#include<cmath>
#include<cstring>
#include<ctime>
#include<cstdlib>
#include<algorithm>
#include<queue>
#include<set>
#include<map>
#define N 51
#define M 10010
#define INF 0x3f3f3f3f
using namespace std;
inline int read()
{
    int f=1,x=0;char c=getchar();
    while(c<'0'||c>'9'){if(c=='-')f=-1;c=getchar();}
    while(c>='0'&&c<='9'){x=x*10+c-'0';c=getchar();}
    return x*f;
}
struct rec{
    int next,ver,leng;
}g[M<<1];
int head[M],tot,d[M],n,num;
int is[N],home[N];
inline void add(int x,int y,int val)
{
    g[++tot].ver=y,g[tot].leng=val;
    g[tot].next=head[x],head[x]=tot;
}
inline bool bfs()
{
    memset(d,0,sizeof(d));
    queue<int> q;
    d[0]=1;q.push(0);
    while(q.size()){
        int x=q.front();q.pop();
        for(int i=head[x];i;i=g[i].next){
            int y=g[i].ver,z=g[i].leng;
            if(!z||d[y]) continue;
            d[y]=d[x]+1;
            q.push(y);
            if(y==n*2+1) return 1;
        }
    }
    return 0;
}
inline int dinic(int x,int flow)
{
    if(x==n*2+1) return flow;
    int rest=flow;
    for(int i=head[x];i;i=g[i].next){
        int y=g[i].ver,z=g[i].leng;
        if(!z||d[y]!=d[x]+1) continue;
        int k=dinic(y,min(rest,z));
        if(!k) d[y]=0;
        else{
            g[i].leng-=k;
            g[i^1].leng+=k;
            rest-=k;
        }
    }
    return flow-rest;
}
int main()
{
    int T;
    T=read();
    while(T--){
        memset(head,0,sizeof(head));
        memset(is,0,sizeof(is));//在校学生为 1 
        memset(home,0,sizeof(home));//回家的人为 1 
        tot=1,num=0;
        n=read();
        for(int i=1;i<=n;++i){
            is[i]=read();
            if(is[i]) add(i+n,n*2+1,1),add(n*2+1,i+n,0);
        }
        for(int i=1;i<=n;++i){
            home[i]=read();
            if(!home[i]||!is[i]) add(0,i,1),add(i,0,0),num++;
        }
        for(int i=1;i<=n;++i)
            for(int j=1;j<=n;++j){
                int x=read();
                if(j>i) continue;
                if(i==j&&!home[i]) add(i,i+n,1),add(i+n,i,0);
                else if(x) add(i,j+n,1),add(j+n,i,0),add(j,i+n,1),add(i+n,j,0);
            }
        int now,ans=0;
        while(bfs())
            while((now=dinic(0,INF))) ans+=now;
        if(ans==num) printf("^_^\n");
        else printf("T_T\n");
    }
    return 0;
}

Guess you like

Origin www.cnblogs.com/DarkValkyrie/p/11425697.html