P11693 [JRKSJ ExR] 构造字符串使得

P11693 [JRKSJ ExR] 构造字符串使得

题目描述

给你一张 n 个点 m 条边的无向图。现在有一枚棋子初始在点 x。双人博弈,先后手轮流移动棋子,每次可以将棋子移动到图上任意一个「与当前棋子所在结点有边直接相连」的结点。保证每个结点都有至少一条边与之相连

有一初值为 0 的变量 v每次移动过后,记当前棋子所在结点编号为 t,则将 v 赋值为 max(v,t)。也就是说,v 的值是棋子移动到过的结点编号最大值且棋子的初始位置 x 一开始并不计算在内

现在先后手总共移动 k 次棋子,先手希望最终 v 尽可能大,后手希望最终 v 尽可能小。

共有 q 次询问,每次询问给出 x,k,询问假如从 x 开始一次共 k 步的博弈,若双方均采用最优策略,那么最终 v 的值为多少。

对于所有数据,保证 2n2×1051m5×1051q2×1051x,kn

保证给出的图无重边、无自环,保证对于任意点 u 至少存在一个点 v 使得 u,v 之间存在一条边。

Solution:

说句闲话:

比赛场切了这题,嘻嘻
刚写完就被勒令回学校了,不嘻嘻
至于回学校的原因嘛,竟然是校长要表彰我们这种天天请假不上课的 竞赛拿奖的 😄 。

言归正传:

我们不难发现博弈的总步数其实就三种: 一步,两步和三步。一步的做法很显然,对于走两步以上的:我们来考虑一个子问题:假设你现在是第二步时的 player2,你该如何走使得权值最小。

对于子问题:

如果你此时只有一步了,那么你可以直接走向所有与 pos1 相连的节点中权值最小的

如果你在此时还有两步及以上,那么无论 p1 在第3步时选了什么,p2 只需要在第 4 步时选回第 2 步的点就好了。
那么显然 p1 一定会选一个在 pos2 能一步到达的点中点权最大的来做 pos3

所以我们先维护一下每个点的邻居的点权的的最大值 w2,那么作为 p2 的你会选择在 pos1 的所有邻居中 max(w2,pos2) 最小的点来做 pos2 。我们将这个子问题的答案记为 game

那么原问题的解显然就是与初始点 pos0 相邻的所有子问题中,game 的最大值。

Code:

#include<bits/stdc++.h>
const int N=2e5+5;
const int inf=1e9;
using namespace std;
vector<int> E[N];
int w[3][N],ans[3][N],game[N],mx[N];
int n,m,q;
void work()
{
cin>>n>>m>>q;
for(int i=1;i<=n;i++)
{
w[2][i]=inf;w[1][i]=inf;game[i]=inf;
}
for(int i=1,x,y;i<=m;i++)
{
scanf("%d%d",&x,&y);
E[x].push_back(y);
E[y].push_back(x);
w[0][x]=max(w[0][x],y);w[0][y]=max(w[0][y],x);
w[1][x]=min(w[1][x],y);w[1][y]=min(w[1][y],x);
w[2][x]=min(w[2][x],y);w[2][y]=min(w[2][y],x);
}
for(int i=1;i<=n;i++)
{
w[1][i]=max(w[1][i],i);
if(w[2][i]==inf)w[2][i]=0;
ans[0][i]=w[0][i];
}
for(int x=1;x<=n;x++)for(auto y : E[x])
{
ans[2][x]=max({ans[2][x],w[2][y],y});
game[x]=min(game[x],max(y,w[0][y]));
ans[1][x]=max(ans[1][x],w[1][y]);
}
for(int x=1;x<=n;x++)for(auto y : E[x])mx[x]=max(mx[x],game[y]);
for(int i=1;i<=n;i++)ans[2][i]=max(ans[2][i],mx[i]);
for(int i=1,x,k;i<=q;i++)
{
scanf("%d%d",&x,&k);
k= (k>3 ? 3 : k);
k--;
printf("%d\n",ans[k][x]);
}
}
int main()
{
//freopen("T1.in","r",stdin);freopen("T1.out","w",stdout);
work();
return 0;
}
posted @   liuboom  阅读(3)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 微软正式发布.NET 10 Preview 1:开启下一代开发框架新篇章
· 没有源码,如何修改代码逻辑?
· PowerShell开发游戏 · 打蜜蜂
· 在鹅厂做java开发是什么体验
· WPF到Web的无缝过渡:英雄联盟客户端的OpenSilver迁移实战
点击右上角即可分享
微信分享提示