社区讨论
玄学匈牙利
P2055[ZJOI2009] 假期的宿舍参与者 1已保存回复 0
讨论操作
快速查看讨论及其快照的属性,并进行相关操作。
- 当前回复
- 0 条
- 当前快照
- 1 份
- 快照标识符
- @mi6n326i
- 此快照首次捕获于
- 2025/11/20 07:34 4 个月前
- 此快照最后确认于
- 2025/11/20 07:34 4 个月前
P2055 [ZJOI2009]假期的宿舍
kuai匈牙利bfs板子(AC)但是没过
换成dfs就对了???
CPP#include <algorithm>
#include <iostream>
#include <cstring>
#include <cstdio>
#include <queue>
#define ul unsigned long long
#define RG register int
#define rg register int
#define ll long long
#define il inline
#define INF 2147483647
#define SZ 1000000
using namespace std;
il int GI()
{
RG x=0,o=1;char ch=getchar();
while((ch!='-') && (ch<'0'||ch>'9')) ch=getchar();
if(ch == '-') o=0,ch=getchar();
while(('0'<=ch) && (ch<='9')) x=(x<<3)+(x<<1)+ch-'0',ch=getchar();
return o?x:-x;
}
struct Edge{int to,nxt;}e[SZ];
int Ehead[SZ],Ecnt=1;
il void Eadd(int u,int v)
{
e[Ecnt]=(Edge){v,Ehead[u]};
Ehead[u]=Ecnt++;
}
int n,I[1000],J[1000];
/*
CPPint pre[SZ],mat[SZ],vis[SZ];
queue <int> Q; bool flg;
il int Hung()
{
RG Ans = 0;
memset(vis,-1,sizeof(vis));
memset(mat,-1,sizeof(mat));
for(RG i=1;i<=n;++i)
{
if(mat[i]!=-1) continue;
while(!Q.empty()) Q.pop();
Q.push(i) , pre[i]=-1, flg=0;
while((!Q.empty()) && (!flg))
{
RG u=Q.front();Q.pop();
for(RG j=Ehead[i];j;j=e[j].nxt)
{
RG v=e[i].to;
if(vis[v]==i) continue;
vis[v]=1;
if(mat[v]>0) pre[mat[v]]=u,Q.push(v);
else
{
flg = 1;
RG a=u,b=v;
while(a!=-1)
{
RG c=mat[a];
mat[a]=b,mat[b]=a;
a=pre[a],b=c;
}
}
}
}
if(mat[i]!=-1) ++Ans;
}
return Ans;
}
*/
int pre[SZ],mat[SZ],vis[SZ]; //MAT : 前面 pre : 前面的前面
CPPqueue <int> Q;bool flg;
il int Hung()
{
rg Ans=0;
memset(vis,-1,sizeof(vis));
memset(mat,-1,sizeof(mat));
for(rg i=1;i<=n;++i)
{
if( I[i] && J[i] ) continue;
if(mat[i]!=-1) continue;
while(!Q.empty()) Q.pop();
Q.push(i),pre[i]=-1,flg=0;
while(!Q.empty() && !flg)
{
rg u=Q.front();Q.pop();
for(rg j=Ehead[u];(j)&&(!flg);j=e[j].nxt)
{
rg v=e[j].to;
if(vis[v]==i) continue;
vis[v]=i;
if(mat[v]>=0) pre[mat[v]]=u,Q.push(mat[v]);
else
{
flg=1;
rg a=u,b=v;
while(a!=-1)
{
rg c=mat[a];
mat[a]=b;
mat[b]=a;
a=pre[a];
b=c;
}
}
}
}
if(mat[i]!=-1) Ans++;
}
return Ans;
}
// 连边 case1: 认识在学校的人
// case2: 在学校且不离开,跟自己连
/*
CPPbool DFS(int x)
{
for(int i=Ehead[x];i;i=e[i].nxt)
{
int v=e[i].to;
if(!vis[v])
{
vis[v]=true;
if(!mat[v]||DFS(mat[v]))
{
mat[v]=x;
return true;
}
}
}
return false;
}
*/
CPPil void work()
{
memset(Ehead,0,sizeof(Ehead)),Ecnt=1;
n=GI();
RG tot=0; //统计需要床的总人数
for(RG i=1;i<=n;++i)
{
I[i]=GI();
if( !I[i] )
++tot; // 不在学校的人需要床
}
for(RG i=1;i<=n;++i)
{
J[i]=GI();
if( !J[i] && I[i] )
Eadd(i,i) , ++tot; //留校生 也需要床 并且自己的床也可以睡
}
for(RG i=1;i<=n;++i)
for(RG j=1;j<=n;++j)
{
RG IN=GI();
if( IN && I[j] ) //认识 并且那人在学校 就可以睡
Eadd(i,j);
}
/* memset(mat,0,sizeof(mat));
RG sum=0;
for(int i=1;i<=n;++i)
{
if((I[i]&&J[i]==0)||!I[i])//要么是学生在学校,要么是外来的人
{
memset(vis,0,sizeof(vis));
if(DFS(i))++sum;
}
}*/
if(Hung()==tot) cout<<"^_^\n";
else cout<<"T_T\n";
}
int main()
{
RG T=GI();
while(T--) work();
return 0;
}
回复
共 0 条回复,欢迎继续交流。
正在加载回复...