zoukankan      html  css  js  c++  java
  • ZJOI2009 假期的宿舍

    传送门

    这还是很显然是一道二分图匹配的题……(看数据范围辣么小)

    其实这题就是建图稍微复杂一点。对于每个学生,我们把他们的床连到汇点上,然后对于每个没回家的和外来的人,我们把他们连到源点上,之后在人和床之间就按给定的关系连上就可以。注意自己和自己的床要连一条边。

    处理过程比较繁琐……我们可以选择用1~n表示人,n+1~2*n表示床,其中n+i表示第i个人的床。这样的话即使有一些人不在校,我们也可以连边,反正他们和源汇点也不联通,计算的时候没什么关系。

    之后直接跑dinic即可。(仍然不会匈牙利)

    上代码。

    #include<cstdio>
    #include<algorithm>
    #include<cstring>
    #include<cmath>
    #include<iostream>
    #include<queue>
    #define rep(i,a,n) for(int i = a;i <= n;i++)
    #define per(i,n,a) for(int i = n;i >= a;i--)
    #define enter putchar('
    ')
    
    using namespace std;
    const int M = 505;
    const int N = 100005;
    const int INF = 1e9;
    typedef long long ll;
    
    int read()
    {
        int ans = 0,op = 1;
        char ch = getchar();
        while(ch < '0' || ch > '9')
        {
            if(ch == '-') op = -1;
            ch = getchar();
        }
        while(ch >= '0' && ch <= '9')
        {
            ans *= 10;
            ans += ch - '0';
            ch = getchar();
        }
        return ans * op;
    }
    
    struct node
    {
        int from,next,to,v;
    }e[N];
    int t,n,deep[M],g[55][55],bcnt,scnt,ecnt = -1,head[M],cur[M],maxflow,source,sink;
    bool stu[M],out[M];
    queue <int> q;
    
    void add(int x,int y,int z)
    {
        e[++ecnt].from = x;
        e[ecnt].to = y;
        e[ecnt].v = z;
        e[ecnt].next = head[x];
        head[x] = ecnt;
    }
    
    void clear()
    {
        memset(stu,0,sizeof(stu));
        memset(out,0,sizeof(out));
        memset(head,-1,sizeof(head));
        memset(cur,-1,sizeof(cur));
        ecnt = -1,bcnt = scnt = maxflow = 0;
        memset(e,0,sizeof(e));
        source = 0,sink = 105;
    }
    
    void build()
    {
        n = read();
        rep(i,1,n) 
        {
            stu[i] = read();
            if(stu[i]) add(i+n,sink,1),add(sink,i+n,0);
        }
        rep(i,1,n)
        {
            out[i] = read();
            if(stu[i] && !out[i]) add(source,i,1),add(i,source,0),scnt++;
            if(!stu[i]) add(source,i,1),add(i,source,0),scnt++;
        }
        rep(i,1,n)
            rep(j,1,n) 
            {
                g[i][j] = read();
                if(i == j && stu[i] && !out[i]) add(i,i+n,1),add(i+n,i,0);
                if(g[i][j]) add(i,j+n,1),add(j+n,i,0);  
            }
    }
    
    bool bfs(int s,int t)
    {
        memset(deep,-1,sizeof(deep));
        while(!q.empty()) q.pop();
        rep(i,0,sink+1) cur[i] = head[i];
        deep[s] = 0,q.push(s);
        while(!q.empty())
        {
            int k = q.front();q.pop();
            for(int i = head[k];i != -1;i = e[i].next)
            {
                if(deep[e[i].to] == -1 && e[i].v)
                deep[e[i].to] = deep[k] + 1,q.push(e[i].to);
            }
        }
        if(deep[t] == -1) return 0;
        else return 1;
    }
    
    int dfs(int s,int t,int limit)
    {
        if(!limit || s == t) return limit;
        int flow = 0;
        for(int i = cur[s];i != -1;i = e[i].next)
        {
            cur[s] = i;
            if(deep[e[i].to] != deep[s] + 1) continue;
            int f = dfs(e[i].to,t,min(limit,e[i].v));
            if(f)
            {
                e[i].v -= f,e[i^1].v += f ;
                flow += f,limit -= f;
                if(!limit) break;
            }
        }
        if(!flow) deep[s] = -233333;
        return flow;
    }
    
    void dinic(int s,int t)
    {
        while(bfs(s,t)) maxflow += dfs(s,t,INF);
    }
    
    int main()
    {
        t = read();
        while(t--)
        {
            clear();
            build();
            dinic(source,sink);
            if(maxflow == scnt) printf("^_^
    ");
            else printf("T_T
    ");
        }
        return 0;
    }
  • 相关阅读:
    3G 4G 5G中的网络安全问题——文献汇总
    成都Uber优步司机奖励政策(4月4日)
    北京Uber优步司机奖励政策(4月4日)
    滴滴快车奖励政策,高峰奖励,翻倍奖励,按成交率,指派单数分级(4月4日)
    北京Uber优步司机奖励政策(4月3日)
    滴滴快车奖励政策,高峰奖励,翻倍奖励,按成交率,指派单数分级(4月3日)
    北京Uber优步司机奖励政策(4月2日)
    成都Uber优步司机奖励政策(4月2、3日)
    滴滴快车奖励政策,高峰奖励,翻倍奖励,按成交率,指派单数分级(4月2日)
    Spark入门(Python版)
  • 原文地址:https://www.cnblogs.com/captain1/p/9563244.html
Copyright © 2011-2022 走看看