首先,我不会
然后,我旁边的大佬,ta一看,原来是二分图(年轻人,不讲武德)
直接看:玩具是和空位置形成一个二分图,可以对于每一个有玩具的点先跑一个dfs找边(放心,只有50,不会T掉)
最后跑一个匈牙利算法
然后我们就可以贴代码了:
#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
int n,head[51],xia[5001],tot,to[5001],T;
int head2[51],xia2[5001],to2[5001],tot2,m;
int match[51],qu[51];
bool zha[51],ok[51];
void dfs(int x,int ti,int st){
if(ti == T+1) return ;
ok[x] = 1;
if(!zha[x]) {
xia[++tot] = head[st];
head[st] = tot,to[tot] = x;
}
for(int i(head2[x]);i;i=xia2[i]){
int j(to2[i]);
if(ok[j]) continue;
dfs(j,ti+1,st);
}
}
bool dfs2(int x) {
ok[x] = 1;
for(int i(head[x]);i;i=xia[i]) {
int j=to[i];
if(ok[match[j]]) continue;
if(!match[j]||dfs2(match[j])){
match[j] = x;
return 1;
}
}
return 0;
}
int main(){
scanf("%d%d",&n,&T);int x,ans(0);
for(int i(2);i<=n;++i){
scanf("%d",&x); ++x;
xia2[++tot2] = head2[i];
head2[i] = tot2,to2[tot2] = x;
xia2[++tot2] = head2[x];
head2[x] = tot2,to2[tot2] = i;
}
scanf("%d",&m);
for(int i(1);i<=m;++i){
scanf("%d",&qu[i]);++qu[i];zha[qu[i]] = 1;
}
for(int i(1);i<=n;++i){
if(zha[i]==1) {
memset(ok,0,sizeof(ok));
dfs(i,0,i);
}
}
memset(ok,0,sizeof(ok));
for(int i(1);i<=m;++i){
if(!match[qu[i]]&&dfs2(qu[i])) {
++ans;
memset(ok,0,sizeof(ok));
}
}
printf("%d",ans);
return 0;
}


京公网安备 11010502036488号