链接
https://www.luogu.org/record/show?rid=7930133
大意
有一些人,他们可能认识可能不认识,认识的人可以把自己的床给别人睡,有些人不需要床,有些人有床,请问能否让所有需要睡觉的人都有一张床,如果可以输出一个奇怪的字符,如果不可以输出另一个奇怪的字符
思路
毫无疑问,这是一个二分图最大匹配的裸题,照理说本来是应该用匈牙利的,但是因为要求联系最大流,所以就打了这个代码
这道题最大流的核心在于建图,其它的套板子就行了!
代码
#include<cstring>
#include<cstdio>
#include<queue>
#define min(a,b) a<b?a:b
#define N 5001
#define pyes printf("^_^\n")
#define puno printf("T_T\n")
using namespace std;int f,p,k,n;char c;
int read()
{
f=0;p=1;
while(c=getchar(),c<=47||c>=58) if(c=='-') p=-1;f=(f<<3)+(f<<1)+c-48;
while(c=getchar(),c>=48&&c<=57) f=(f<<3)+(f<<1)+c-48;
return p*f;
}
struct node{int next,to,w;}e[N];int l[N],tot,d[N],s=0,t=1001,sum;bool a[N],x;
void qk()
{
tot=0;sum=0;
memset(e,0,sizeof(e));
memset(l,-1,sizeof(l));
return;
}
void add(int u,int v,int w)
{
e[tot].next=l[u];e[tot].to=v;e[tot].w=w;l[u]=tot++;
e[tot].next=l[v];e[tot].to=u;e[tot].w=0;l[v]=tot++;
return;
}
bool bfs()
{
memset(d,-1,sizeof(d));
queue<int>q;d[s]=0;q.push(s);
while(q.size())
{
int x=q.front();q.pop();
for(int i=l[x];i!=-1;i=e[i].next)
{
int y=e[i].to;
if(e[i].w&&d[y]==-1)
{
d[y]=d[x]+1;
q.push(y);
if(y==t) return true;
}
}
}
return false;
}
int dfs(int x,int flow)
{
if(x==t||!flow) return flow;
int rest=0,k=0;
for(int i=l[x];i!=-1;i=e[i].next)
{
int y=e[i].to;
if(d[x]+1==d[y]&&e[i].w)
{
f=dfs(y,min(flow-rest,e[i].w));
e[i].w-=f;rest+=f;e[i^1].w+=f;
if(rest==flow) return flow;
}
}
if(!rest) d[x]=0;
return rest;
}
int dinic()
{
int r=0;
while(bfs()) r+=dfs(s,2147483647);
return r;
}
int main()
{
k=read();
while(k--)
{
n=read();
qk();
for(int i=1;i<=n;i++)
{
a[i]=read();
if(a[i]) add(i+n,t,1);
}
for(int i=1;i<=n;i++)
{
x=read();
if(!a[i]||(a[i]&&!x)) add(s,i,1),sum++;
}
for(int i=1;i<=n;i++)
for(int j=1;j<=n;j++)
{
x=read();
if(i==j||x) add(i,j+n,1);//记得自己也可以睡自己的床
}
if(dinic()==sum) pyes;else puno;
}
}