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

    Description

    Input

    Output

    Sample Input

    1
    3
    1 1 0
    0 1 0
    0 1 1
    1 0 0
    1 0 0

    Sample Output

    ˆ ˆ

    HINT

    对于30% 的数据满足1 ≤ n ≤ 12。
    对于100% 的数据满足1 ≤ n ≤ 50,1 ≤ T ≤ 20。

     
    正解:二分图匹配(匈牙利算法)
    解题报告:
      直接跑匈牙利算法。注意连边的关系,只有当i需要床位而且j可能提供床位时才连边,而且i不回家时,向自己连边。
      注意最大匹配的时候vis数组不能记i本身,因为可以匹配自己。细节问题。
     
     1 //It is made by jump~
     2 #include <iostream>
     3 #include <cstdlib>
     4 #include <cstring>
     5 #include <cstdio>
     6 #include <cmath>
     7 #include <algorithm>
     8 #include <ctime>
     9 #include <vector>
    10 #include <queue>
    11 #include <map>
    12 #include <set>
    13 #ifdef WIN32   
    14 #define OT "%I64d"
    15 #else
    16 #define OT "%lld"
    17 #endif
    18 using namespace std;
    19 typedef long long LL;
    20 const int MAXN = 51;
    21 int n,ans,cnt,a[MAXN][MAXN],b[MAXN],c[MAXN],match[MAXN];
    22 bool vis[MAXN];
    23 
    24 inline int getint()
    25 {
    26        int w=0,q=0;
    27        char c=getchar();
    28        while((c<'0' || c>'9') && c!='-') c=getchar();
    29        if (c=='-')  q=1, c=getchar();
    30        while (c>='0' && c<='9') w=w*10+c-'0', c=getchar();
    31        return q ? -w : w;
    32 }
    33 
    34 inline bool dfs(int x){
    35     //不能加这一步!!!可能会匹配自己!!!
    36     //vis[x]=1
    37     for(int i=1;i<=n;i++) {
    38     if(a[x][i] && !vis[i]) {
    39         vis[i]=1;
    40         if(!match[i] || dfs(match[i])) {
    41         match[i]=x;
    42         // match[x]=i;不能标记两边
    43         return true;
    44         }
    45     }
    46     }
    47     return false;
    48 }
    49 
    50 inline void work(){
    51     int T=getint();
    52     while(T--) {
    53     memset(a,0,sizeof(a));memset(match,0,sizeof(match));
    54     n=getint(); ans=0; cnt=0;
    55     for(int i=1;i<=n;i++) b[i]=getint(); for(int i=1;i<=n;i++) c[i]=getint();
    56     for(int i=1;i<=n;i++) if(!b[i] || (b[i]&&!c[i])) cnt++;//统计需要床位的人数
    57     int x;
    58     for(int i=1;i<=n;i++) {
    59         for(int j=1;j<=n;j++) {
    60         x=getint(); 
    61         if(x && ((b[i] && !c[i]) || !b[i] ) &&b[j]) //表示i需要床位,而且i、j认识,并且j可能提供床位
    62             a[i][j]=1;
    63         }
    64         if(b[i] && !c[i]) a[i][i]=1;//留校的在校生肯定可以睡自己床上
    65     }
    66     for(int i=1;i<=n;i++) {
    67         memset(vis,0,sizeof(vis));
    68         if(dfs(i)) ans++;       
    69     }        
    70     if(ans==cnt) printf("^_^
    ");
    71     else printf("T_T
    ");
    72     }
    73 }
    74 
    75 int main()
    76 {
    77   work();
    78   return 0;
    79 }
  • 相关阅读:
    MATLAB 高斯金字塔
    MATLAB 灰度图直方图均衡化
    MATLAB 生成高斯图像
    MATLAB 灰度、二值图像腐蚀膨胀
    MATLAB 中值滤波
    MATLAB 最大中值滤波
    MATLAB 最大均值滤波
    MATLAB 图像加噪,各种滤波
    MATLAB 图像傅里叶变换,幅度谱,相位谱
    十款最佳人工智能软件
  • 原文地址:https://www.cnblogs.com/ljh2000-jump/p/5767765.html
Copyright © 2011-2022 走看看