zoukankan      html  css  js  c++  java
  • LuoguP2055 [ZJOI2009]假期的宿舍【二分图最大匹配】By cellur925

    题目传送门

    这道题开始感觉不出是二分图最大匹配的qwq。但是今天学了匈牙利算法,想来做几个题qwq。做这个题的时候想了很久它哪里是二分图,脑子里是“两列,每列有很多点的那种图 qwq。”

    然后看了题解,发现竟是这样简单qwq。

    关键还在建图。

    首先把本校且不回家的学生自己向自己连一条边,之后再把和自己认识的还是本校的学生连一条边(不用管他回不回家),之后跑一遍最大匹配就成了。

    回顾一下我们发现,它确实满足“任意两条边没有公共端点”的性质,因为我们暂时排除了基♂的情况,不会有两个人睡在一张床上。

    然后注意在主程序中跑匹配的时候,不是每个点都跑,而是那些有住宿需求的人跑。(为此WA了两次qwq)

    Code

     1 #include<cstdio>
     2 #include<cstring>
     3 #include<algorithm>
     4 
     5 using namespace std;
     6 
     7 int T,n,sta,ans,tot;
     8 int stu[100],head[100],home[100],match[100];
     9 bool vis[100];
    10 struct node{
    11     int to,next;
    12 }edge[10000];
    13 
    14 void add(int x,int y)
    15 {
    16     edge[++tot].to=y;
    17     edge[tot].next=head[x];
    18     head[x]=tot;
    19 }
    20 
    21 bool dfs(int x)
    22 {
    23     for(int i=head[x];i;i=edge[i].next)
    24     {
    25         int y=edge[i].to;
    26         if(!vis[y])
    27         {
    28             vis[y]=1;
    29             if(!match[y]||dfs(match[y]))
    30             {
    31                 match[y]=x;
    32                 return 1;
    33             }
    34         }
    35     }
    36     return 0;
    37 }
    38 
    39 int main()
    40 {
    41     scanf("%d",&T);
    42     while(T--)
    43     {
    44         scanf("%d",&n);
    45         for(int i=1;i<=n;i++) scanf("%d",&stu[i]);
    46         for(int i=1;i<=n;i++)
    47         {
    48             if(stu[i]) scanf("%d",&home[i]);
    49             else scanf("%d",&home[0]);
    50             if(!home[i]&&stu[i]) add(i,i);
    51         }       
    52         for(int i=1;i<=n;i++)
    53             for(int j=1;j<=n;j++)
    54             {
    55                 int x=0;
    56                 scanf("%d",&x);
    57                 if(x&&stu[j]) add(i,j);
    58             }
    59         for(int i=1;i<=n;i++)
    60             if(!stu[i]||(!home[i]&&stu[i])) sta++;        
    61         for(int i=1;i<=n;i++)
    62             if(!stu[i]||(!home[i]&&stu[i]))
    63             {
    64                 memset(vis,0,sizeof(vis));
    65                 if(dfs(i)) ans++;
    66             }
    67         if(ans==sta) printf("^_^
    ");
    68         else printf("T_T
    ");
    69         memset(match,0,sizeof(match));
    70         memset(head,0,sizeof(head));
    71         sta=0,ans=0,tot=0;
    72     }
    73     return 0;
    74 }
    View Code
  • 相关阅读:
    你了解幻读吗?
    http面试准备
    DNS域名解析过程,域名的认识
    ajax实现用户登陆,退出,java做后端
    serialize()与serializeArray()
    jquery中Json操作
    jquery字符串操作
    理解jQuery的$.extend与$.fn.extend
    HTML之间互相传参
    解决topjui中工具栏按钮删除刷新从属表
  • 原文地址:https://www.cnblogs.com/nopartyfoucaodong/p/9696001.html
Copyright © 2011-2022 走看看