题意:
给你一个n点m条边k个人,然后和k个人的位置。然后每一秒每个人可以到他相邻的点去,而且必须移动,问你是否有一点可以使得这k个人在某一秒都集合在某一点。
思考:
一看树上问题,还有每秒必须走,很明显就知道有个点到其他人所在的点的距离必须奇偶,这样才能保证能集合。但是这个奇偶性怎么判断呢,用lca直接求每个点到其他点的距离是不现实的,数据太大了。所以可以直接进行染色判断,从第一个点开始,每隔一点染一色,看看最后是否k个人所在的点都是同颜色。由于这个数可能有环,所以一个点可能有两个颜色,所以再染一次。
代码:
int T,n,m,k;
int va[N];
int col[N][2];
vector<PII > v;
vector<int > e[N];
void dfs(int now)
{
for(auto spot:e[now])
{
if(col[now][0])
{
if(!col[spot][1])
{
col[spot][1] = 1;
dfs(spot);
}
}
if(col[now][1])
{
if(!col[spot][0])
{
col[spot][0] = 1;
dfs(spot);
}
}
}
}
signed main()
{
IOS;
cin>>n>>m>>k;
for(int i=1;i<=m;i++)
{
int a,b;
cin>>a>>b;
e[a].pb(b);
e[b].pb(a);
}
for(int i=1;i<=k;i++) cin>>va[i];
col[1][0] = 1;
dfs(1);
int suc1 = 1,suc2 = 1;
for(int i=1;i<=k;i++)
{
if(col[va[i]][0]==0) suc1 = 0;
if(col[va[i]][1]==0) suc2 = 0;
}
if(suc1||suc2) cout<<"YES\n";
else cout<<"NO\n";
return 0;
}
总结:
将复杂的问题多多简单化。