zoukankan      html  css  js  c++  java
  • 洛谷P2055假期的宿舍

    题目

    此题主要是考察二分图匹配,而二分图匹配最主要的就是建图,而图一般都是要分成两个部分来分,比如该题就需要先将在学校住的人和床连在一起,因为在学校住就会与一个床。然后每两个人之间假如他们相互认识就可以相互连边,这样就可以通过人人相连实现人床相连。

    (Code)

    #include <iostream>
    #include <algorithm>
    #include <cstring>
    #include <cstdio>
    #include <cmath>
    #pragma GCC optimize(2)
    #pragma GCC optimize(3)
    using namespace std;
    int n1, T, cnt;
    int map[1010][1010];
    int vis[200100], lin[200010], school[200100], home[200010], flag[200100];
    struct cym {
        int to, nex;
    }e[200010];
    inline void add(int f, int t)
    {	
        e[++cnt].to = t;
        e[cnt].nex = lin[f];
        lin[f] = cnt;
    }	
    inline bool dfs(int now)
    {	
        for (int i = lin[now]; i; i = e[i].nex)
            if (!vis[e[i].to])
            {
                vis[e[i].to] = 1;
                if (!flag[e[i].to] || dfs(flag[e[i].to])) {
                    flag[e[i].to] = now; return true;
                }	
            }
        return false;
    } 	
    int main()
    {	
        scanf("%d", &T);
        while (T--)
        {
            int ans = 0, sum = 0;
            memset(map, 0, sizeof(map)); memset(school, 0, sizeof(school));memset(home, 0, sizeof(home));memset(flag, 0, sizeof(flag));memset(e, 0, sizeof(e));memset(lin, 0, sizeof(lin));
            cnt = 0;
    		scanf("%d", &n1);
            for (int i = 1; i <= n1; i++)
                scanf("%d", &school[i]);
            for (int i = 1; i <= n1; i++)
            {
                scanf("%d", &home[i]);
                if (!school[i])
                	home[i] = 0;
                if (school[i])	
                    add(i, i);
            }
            for (int i = 1; i <= n1; i++)
            	if (!home[i])
            		sum++;
            for (int i = 1; i <= n1; i++)
                for (int j = 1; j <= n1; j++)
                {
                    scanf("%d", &map[i][j]);
                    if (map[i][j] && school[j])	
                        add(i, j);
                }
            for (int i = 1; i <= n1; i++)
                if (!home[i])
                {
                    memset(vis, 0, sizeof(vis));
                    if (dfs(i)) ans++;	
                }
            if (ans == sum) printf("^_^
    ");
            else printf("T_T
    ");
        }
        return 0;
    }
    /*
    2    	 
    3    	 
    1 1 0
    0 1 0
    0 0 1
    0 0 0
    1 0 0
    3    	 
    1 1 0
    0 1 0
    0 1 1
    1 0 0
    1 0 0
    */   
    
    
  • 相关阅读:
    [Audio processing] FFMPEG转音频格式和采样率
    [操作系统] OS X Yosemite U盘制作
    [基础] 广义线性回归
    [基础] 一些英文术语
    [经典] 在未排序数组中返回topK大的数
    [参数方法] 贝叶斯估计(待补充)
    [参数方法] 最小二乘
    [Theano] Theano初探
    font awesome的图标在WP8浏览器下无法显示的问题解决
    SQL 获取各表记录数的最快方法
  • 原文地址:https://www.cnblogs.com/liuwenyao/p/10289379.html
Copyright © 2011-2022 走看看