bzoj1433: [ZJOI2009]假期的宿舍 http://www.lydsy.com/JudgeOnline/problem.php?id=1433
把不回家的人拆成两个点 一个是床 一个是人
所以回家的人就只有床一个点 亲朋好友就只有人一个点
那这样就是
床 - 人
其实数据这么水完全可以不用建边 搞一个map直接跑 代码会好看很多
太菜了 一道模版查错查了了几百年
最后查出来一个memset 和一个把i打成j 我也是冇嘢港
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
struct node
{
int x,y,next;
}a[510];
int last[110],len;
int match[110];
int v[110];
int t,sc[60],gh[60],map[60][60];//sh:if a school student? gh:if go home?
int id[60],bedid[60],m,bed; //分别为 人 和 床 的编码
void build(int x,int y)
{
len++;
a[len].x=x;a[len].y=y;a[len].next=last[x];last[x]=len;
}
bool find(int x)
{
for (int k=last[x];k;k=a[k].next)
{
int y=a[k].y;
if (v[y]!=t)
{
v[y]=t;
if (match[y]==0||find(match[y])==1) {match[y]=x;return 1;}
}
}
return 0;
}
int main()
{
//把不回家的人拆成两个点 一个是床 一个是人
//所以回家的人就只有床一个点 亲朋好友就只有人一个点
//那这样就是
/*
床 - 人
*/
freopen("holiday.in","r",stdin);
freopen("holiday.out","w",stdout);
int u;
scanf("%d",&u);
while (u--)
{
int n;
scanf("%d",&n);
memset(last,0,sizeof(last));len=0;
memset(v,0,sizeof(v));
memset(match,0,sizeof(match));
memset(map,0,sizeof(map));
memset(id,0,sizeof(id));
memset(bedid,0,sizeof(bedid));
t=0;bed=0;m=0;
bed=n+1;
for (int i=1;i<=n;i++) scanf("%d",&sc[i]);
for (int i=1;i<=n;i++)
{
scanf("%d",&gh[i]);
if (sc[i]==0) gh[i]=-1;
if (gh[i]==1) bedid[i]=++bed;
else if (gh[i]==0) {bedid[i]=++bed;id[i]=++m;}
else {id[i]=++m;}
}
for (int i=1;i<=n;i++)
{
if (sc[i]==1&&id[i]!=0) build(id[i],bedid[i]);
for (int j=1;j<=n;j++)
{
scanf("%d",&map[i][j]);
if (j<=i) continue;
if (map[i][j])
{
if (sc[i]==1&&sc[j]==1) {if (id[i]!=0) build(id[i],bedid[j]); if (id[j]!=0)build(id[j],bedid[i]);}
else if (sc[i]==1&&sc[j]==0) {build(id[j],bedid[i]);}
else if (sc[i]==0&&sc[j]==1) {build(id[i],bedid[j]);}
}
}
}
if (bed-n-1<m) {printf("T_T\n");continue;}
int ans=0;
for (int i=1;i<=m;i++)
{
t=i;
if (find(i)) ans++;
}
if (ans==m) printf("^_^\n");
else printf("T_T\n");
}
}