BZOJ 1433 假期的宿舍 二分图匹配

这道题目不难,二分图匹配建模比较明显。加油吧!相信自己。(自己写的,好开心,40毫秒,比ccz略快)。 尽管算法模版是抄一本书上的,但这次很明显我是背出来的。不算抄。

  1 #include<cstdio>
  2 #include<iostream>
  3 #include<vector>
  4 #include<queue>
  5 #include<cstring>
  6 #define rep(i,j,k) for(int i = j; i <= k; i++)
  7 #define maxn 60
  8 #define clr(i,j) memset(i,j,sizeof(i))
  9 using namespace std;
 10
 11 vector<int> g[maxn];
 12 int mx[maxn], my[maxn], dx[maxn], dy[maxn], n1;
 13 queue<int> q;
 14 bool vis[maxn];
 15
 16 bool match(int now)
 17 {
 18     int s = g[now].size();
 19     rep(i,0,s-1){
 20         int to = g[now][i];
 21         if( !vis[to] && dy[to] == dx[now] + 1 ){
 22             vis[to] = 1;
 23             if( !my[to] || match(my[to]) ){
 24                 my[to] = now, mx[now] = to;
 25                 return 1;
 26             }
 27         }
 28     }
 29     return 0;
 30 }
 31
 32 int erfen()
 33 {
 34     clr(mx,0); clr(my,0); int ans = 0;
 35     while( 1 ){
 36         clr(dx,0), clr(dy,0);
 37         while( !q.empty() ) q.pop();
 38         rep(i,1,n1){
 39             if( !mx[i] ) q.push(i);
 40         }
 41         bool flag = 1;
 42         while( !q.empty() ){
 43             int now = q.front(); q.pop();
 44             int s = g[now].size();
 45             rep(i,0,s-1){
 46                 int to = g[now][i];
 47                 if( !dy[to] ){
 48                     dy[to] = dx[now] + 1;
 49                     if( my[to] ){
 50                         dx[my[to]] = dy[to] + 1;
 51                         q.push(my[to]);
 52                     }
 53                     else flag = 0;
 54                 }
 55             }
 56         }
 57         if( flag ) break;
 58         clr(vis,0);
 59         rep(i,1,n1){
 60             if( !mx[i] && match(i) ) ans++;
 61         }
 62     }
 63     return ans;
 64 }
 65
 66 void clear()
 67 {
 68     rep(i,1,maxn) g[i].clear();
 69 }
 70
 71 int read()
 72 {
 73     int s = 0,t = 1; char c = getchar();
 74     while( !isdigit(c) ){
 75         if( c == ‘-‘ ) t = -1; c = getchar();
 76     }
 77     while( isdigit(c) ){
 78         s = s * 10 + c- ‘0‘; c = getchar();
 79     }
 80     return s * t;
 81 }
 82
 83 bool bed[maxn], home[maxn];
 84 bool used[maxn][maxn];
 85
 86 int main()
 87 {
 88     int t = read();
 89     while( t-- ){
 90         clear();
 91         clr(used,0);  clr(bed,0); clr(home,0);
 92         int n = read();
 93         n1 = n;
 94         rep(i,1,n){
 95             bed[i] = read();
 96         }
 97         int tot = 0;
 98         rep(i,1,n) {
 99             int x = read();
100             if( bed[i] && x == 1 ) {
101                 home[i] = 1;
102                 tot++;
103             }
104         }
105         rep(i,1,n){
106             rep(j,1,n){
107                 int x = read();
108                 if( i == j && bed[i] && !home[i] && !used[i][i] ) {
109                      g[i].push_back(i);
110                      used[i][i] = 1;
111                 }
112                 else if( i != j && x ){
113                     if( bed[i] && !home[j] && !used[j][i] ) {
114                         g[j].push_back(i);
115                         used[j][i] = 1;
116                     }
117                     if( bed[j] && !home[i] && !used[i][j]) {
118                         used[i][j] = 1;
119                         g[i].push_back(j);
120                     }
121                 }
122             }
123         }
124         if( erfen() == n - tot ) printf("%c%c%c\n", 94,95,94);
125         else printf("%c%c%c\n", 84,95,84);
126     }
127
128     return 0;
129 }
时间: 2024-10-29 03:05:10

BZOJ 1433 假期的宿舍 二分图匹配的相关文章

[BZOJ1433][ZJOI2009]假期的宿舍 二分图匹配

题目链接:http://www.lydsy.com/JudgeOnline/problem.php?id=1433 首先留在学校的学生向自己的床连边. 要住在学校里的人向认识的学生的床连边. 跑二分图匹配,看匹配的数量是否等于住在学校的人数. 1 #include<cstdio> 2 #include<cstring> 3 #include<algorithm> 4 using namespace std; 5 int inline readint(){ 6 int N

BZOJ1433 [ZJOI2009]假期的宿舍 二分图匹配 匈牙利算法

原文链接http://www.cnblogs.com/zhouzhendong/p/8372785.html 题目传送门 - BZOJ1433 题解 我们理一理题目. 在校的学生,有自己的床,还可以睡朋友的床. 离校的学生,不占床. 外来的学生,只能睡朋友的床. 然后就是一个裸的二分图匹配了. 代码 #include <cstring> #include <cstdlib> #include <cmath> #include <cstdio> #includ

bzoj 1059: [ZJOI2007]矩阵游戏 二分图匹配

1059: [ZJOI2007]矩阵游戏 Time Limit: 10 Sec  Memory Limit: 162 MBSubmit: 1891  Solved: 919[Submit][Status] Description 小Q是一个非常聪明的孩子,除了国际象棋,他还很喜欢玩一个电脑益智游戏——矩阵游戏.矩阵游戏在一个N*N黑白方阵进行(如同国际象棋一般,只是颜色是随意的).每次可以对该矩阵进行两种操作:行交换操作:选择矩阵的任意两行,交换这两行(即交换对应格子的颜色)列交换操作:选择矩阵

BZOJ 1191: [HNOI2006]超级英雄Hero(二分图匹配)

云神说他二分图匹配从来都是用网络流水过去的...我要发扬他的精神.. 这道题明显是二分图匹配.网络流的话可以二分答案+最大流.虽然跑得很慢.... ---------------------------------------------------------------------------------------- #include<cstdio> #include<cstring> #include<algorithm> #include<iostrea

P2055 [ZJOI2009]假期的宿舍 - 二分图最大匹配

把人和床分开考虑,题目说每个人只能睡和自己直接认识的人的床,就是一种边的关系,但是并不是人与人,实际上人与人之间连边是很难处理的,但是如果把人和床连边,就是一张二分图,左右两边分别是不同的东西,然后求一下最大匹配就好了 没思路的时候换换角度,看能不能搞出什么"新东西"来 注意多组数据不超时的情况下能用memset尽量用,有时候感觉某个数组可以不清空但实际上是需要清空的 还有注意连边的时候没那么简单...看注释吧 #include <algorithm> #include &

bzoj 2744: [HEOI2012]朋友圈 二分图匹配

2744: [HEOI2012]朋友圈 Time Limit: 30 Sec  Memory Limit: 128 MBSubmit: 612  Solved: 174[Submit][Status][Discuss] Description 在很久很久以前,曾经有两个国家和睦相处,无忧无虑的生活着.一年一度的评比大会开始了,作为和平的两国,一个朋友圈数量最多的永远都是最值得他人的尊敬,所以现在就是需要你求朋友圈的最大数目. 两个国家看成是AB两国,现在是两个国家的描述: 1.         

假期的宿舍——二分图模板一个

因为题目并没有给出自己认识自己的数据,所以需要手动从每一个学生向他的床上连一条边,找这个错误找了一个小时. 1 #include<algorithm> 2 #include<iostream> 3 #include<cstring> 4 #include<cstdio> 5 #include<vector> 6 using namespace std; 7 const int N=77; 8 int n,p,beds,res,bed[N],mx[

假期的宿舍 二分图

Code: #include<cstdio> #include<cstring> #include<vector> #include<queue> #include<algorithm> using namespace std; const int maxn=300; const int INF=1000000+233; int C[maxn][maxn],is[maxn],home[maxn],idx[maxn]; int s,t; struc

bzoj 1433: [ZJOI2009]假期的宿舍 -- 最大流

1433: [ZJOI2009]假期的宿舍 Time Limit: 10 Sec  Memory Limit: 162 MB 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. 我们从源点向所有住宿的人连边,从所有的床位连向汇点,然后再从人连向他所