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


    首先明确一下:校内的每个学生都有一张床(只是校内的有)

    思路 :分析题目发现是求所有在校学生能否全部有床睡(注意:只需在校学生有床睡,及不回家的;这个床可以是自己的,也可以是朋友的);于是,这道题我们可以把它想象成一个二分图,如样例图:

    a -> b表示a可以睡b的床(注意:虽然样例中没有2 -> 2的边,但你仔细读题就会发现题目中的原话---

     由于题目里给的是一个邻接矩阵,我们便可以无视蓝点所连出去的边,只用红点去搜就行了(代码里写了也不要紧)

     代码 :

     1 #include <bits/stdc++.h>
     2 #define INF 0x3f3f3f3f
     3 using namespace std;
     4 int T, n, head[201], num, vis[201], choose[201], q[201], w[201], ans, cnt;
     5 struct node
     6 {
     7     int next, to;
     8 }stu[40001];
     9 inline void add(int x, int y)//链式前向星 
    10 {
    11     stu[++num].next = head[x];
    12     stu[num].to = y;
    13     head[x] = num;
    14     return;
    15 }
    16 inline int dfs(int u)//二分图匈牙利算法模板 
    17 {
    18     for(register int i = head[u]; i; i = stu[i].next)
    19     {
    20         int k = stu[i].to;
    21         if(vis[k])
    22         {
    23             continue;
    24         }
    25         vis[k] = 1;
    26         if(!choose[k] || dfs(choose[k]))
    27         {
    28             choose[k] = u;
    29             return 1;
    30         }
    31     }
    32     return 0;
    33 }
    34 signed main()
    35 {
    36     scanf("%d", &T);
    37     while(T--)//多组数据 
    38     {
    39         memset(choose, 0, sizeof(choose));//初始化 
    40         memset(head, 0, sizeof(head));
    41         num = 0;
    42         ans = 0;
    43         cnt = 0;
    44         scanf("%d", &n);
    45         for(register int i = 1; i <= n; ++i)
    46         {
    47             scanf("%d", &q[i]);
    48         }
    49         for(register int i = 1; i <= n; ++i)
    50         {
    51             scanf("%d", &w[i]);
    52             if(q[i] && !w[i])//如果他是本校学生&&他不回家 
    53             {
    54                 add(i, i);//自己可以睡自己的床 
    55             }
    56         }
    57         for(register int i = 1; i <= n; ++i)
    58         {
    59             for(register int j = 1, x; j <= n; ++j)
    60             {
    61                 scanf("%d", &x);
    62                 if(x)
    63                 {
    64                     if(q[i])//如果i是本校学生(及有一张床) 
    65                     {
    66                         add(j, i);//j也可以睡 
    67                     }
    68                     if(q[j])//同理 
    69                     {
    70                         add(i, j);
    71                     }
    72                 }
    73             }
    74         }
    75         for(register int i = 1; i <= n; ++i)
    76         {
    77             if(q[i] && w[i])//如果是本校学生&&不留在学校(如果是外校的就不可能回家啊) 
    78             {
    79                 ++cnt;//记录一下有多少个,以后算答案方便 
    80                 continue;//不用管他有没有床 
    81             }
    82             memset(vis, 0, sizeof(vis)); 
    83             if(!dfs(i))//如果有一个学生没有床 
    84             {
    85                 printf("T_T
    ");//哭了 
    86                 break;
    87             }
    88             else
    89             {
    90                 ++ans;//记录有床的学生数量 
    91             }
    92         }
    93         if(ans == n - cnt)//如果留学校的人都有床 
    94         {
    95             printf("^_^
    ");//笑了 
    96         }
    97     }
    98     return 0;
    99 }
  • 相关阅读:
    git clone time out
    Window版本的nvm下载安装以及配置
    jdk安装目录查询
    idea 快捷键
    faac简介、编译、使用
    socket编程实例TCP
    jsoncpp简介、下载、编译、使用
    时间时区概念及常用时间函数
    开启博客之旅
    找回了用户名和密码
  • 原文地址:https://www.cnblogs.com/qqq1112/p/11332850.html
Copyright © 2011-2022 走看看