​LINK​

二分美丽值 x x x(hh没想到吧)

大于等于 x x x的点标注为 1 1 1,否则标注为 0 0 0

Ⅰ.

若存在一条路径有连续的两个点为 1 1 1,那么我们可以无限走这条点,一定满足条件

因为最后中位数一定是这两个之一

Ⅱ.

否则,走过一个 1 1 1点就必须至少走过一个 0 0 0点,所以重复走动一定不划算

那么我们就要找到一条路径满足 1 1 1的个数大于等于 0 0 0的个数,而且是 01 01 01或 10 10 10交替,不然不合法

至于判断就比较简单了

判断的话,从起点和终点分别开始 b f s bfs bfs

那么遍历所有连接两个 1 1 1点的边,若两侧的点分别能到起点和终点即可

判断的话,也是 b f s bfs bfs,从起点开始一次往 0 / 1 0/1 0/1点扩散,一次往 1 / 0 1/0 1/0点扩散即可

交替扩散判断

#include <bits/stdc++.h>
using namespace std;
const int maxn = 4e5+10;
int n,m,s,t,T,dis1[maxn],dis2[maxn],dis3[maxn],a[maxn],l[maxn],r[maxn];
typedef pair<int,int>p;
struct edge
{
int to,nxt;
}d[maxn]; int head[maxn],cnt=1;
void add(int u,int v){ d[++cnt] = (edge){v,head[u]},head[u] = cnt; }
void bfs(int s,int dis[] )
{
for(int i=1;i<=n;i++) dis[i] = -1;
queue<int>q; q.push( s ); dis[s] = 0;
while( !q.empty() )
{
int u = q.front(); q.pop();
for(int i=head[u];i;i=d[i].nxt)
{
int v = d[i].to;
if( dis[v]==-1 ) dis[v]=dis[u]+1,q.push( v );
}
}
}
void BFS(int s,int dis[],int mid )
{
for(int i=1;i<=n;i++) dis[i] = -1;
queue<p>q; q.push( p(s,a[s]<mid) ); dis[s] = 0;
while( !q.empty() )
{
int u = q.front().first,c = q.front().second; q.pop();
for(int i=head[u];i;i=d[i].nxt)
{
int v = d[i].to;
if( dis[v]!=-1 ) continue;
int ok = ( a[v]<mid )?0:1;
if( ok==c ) q.push( p(v,c^1) ), dis[v] = dis[u]+1;
}
}
}
bool isok(int mid)
{
for(int i=1;i<=m;i++)
{
int q = l[i], w = r[i];
if( a[q]>=mid&&a[w]>=mid&&dis1[q]!=-1&&dis2[w]!=-1 ) return true;
if( a[q]>=mid&&a[w]>=mid&&dis1[w]!=-1&&dis2[q]!=-1 ) return true;
}
if( a[s]<mid&&a[t]<mid ) return false;
BFS(s,dis3,mid);
if( dis3[t]!=-1 ) return true;
else return false;
}
int main()
{
cin >> T;
while( T-- )
{
cin >> n >> m >> s >> t;
for(int i=1;i<=n;i++) cin >> a[i];
for(int i=1;i<=m;i++)
{
scanf("%d%d",&l[i],&r[i]);
add( l[i],r[i] ); add( r[i],l[i] );
}
bfs(s,dis1); bfs(t,dis2);
int l = 1, r = 1e9, ans = -1;
while( r>=l )
{
int mid = l+r>>1;
if( isok(mid) ) l = mid+1,ans=mid;
else r = mid-1;
}
if( dis1[t]==-1 ) cout << "NO\n";
else cout << "YES\n" << ans << endl;
cnt = 1;
for(int i=1;i<=n;i++) head[i] = 0;
}
}