A 美丽的路径
题目描述
叶妹妹非常喜欢图论题,这天她出了一个图论题,有一个nn个点mm条边的无向图,其中第ii个点的点权为 a i a_i ai ,她定义一条点数为 k k k 路径: b 1 b_1 b1 , b 2 b_2 b2 ,…, b k b_k bk ;其中点 b i − 1 b_{i-1} bi−1与点 b i b_i bi 通过一条边直接相连 ( 2 ≤ i ≤ k ) (2\le i\le k) (2≤i≤k),所以路径中可以出现重复的点。她将一条路径的美丽值定义为:假设这条路径的点数为 k k k,那么这条路径的美丽值就是此路径上的所有点的点权中第 ⌊ k / 2 + 1 ⌋ \lfloor k/2+1 \rfloor ⌊k/2+1⌋ 小的点权。现在她会询问你是否存在起点为 s s s 号点并且终点为 t t t 号点的路径,如果存在则先输出 Y E S YES YES,再输出存在的所有路径中的最大的美丽值;否则直接输出 N O NO NO。
输入描述:
有多组样例,第一行输入一个数TT,表述样例组数
对于每组样例,第一行先输入四个数 n , m , s , t n,m,s,t n,m,s,t,保证 1 ≤ s ≤ n , 1 ≤ t ≤ n 1\le s\le n,1\le t\le n 1≤s≤n,1≤t≤n
第二行输入 n n n 个数,其中第 i i i 个数为 a i a_i ai ,表示第 i i i 个点的点权
接下来输入 m m m 行,第 i i i 行输入两个数 x i x_i xi 和 y i y_i yi,表示点 x i x_i xi 与点 y i y_i yi之间有一条无向边,保证 1 ≤ x i ≤ n , 1 ≤ y i ≤ n 1\le x_i\le n,1\le y_i\le n 1≤xi≤n,1≤yi≤n
【数据规模与约定】
1 ≤ T ≤ 10 , 1 ≤ n ≤ 2 ∗ 1 0 5 , 0 ≤ m ≤ 2 ∗ 1 0 5 , 1 ≤ a i ≤ 1 0 9 1\le T\le10,1\le n\le 2*10^5,0\le m\le2*10^5,1\le a_i\le10^9 1≤T≤10,1≤n≤2∗105,0≤m≤2∗105,1≤ai≤109
输出描述:
如果存在起点为 s s s 号点并且终点为 t t t 号点的路径,则第一行输出 Y E S YES YES,第二行输出存在的所有的路径中的最大的美丽值;否则直接输出 N O NO NO
分析:
首先,如果不存在从 s s s 到 t t t 的路径,则直接输出 N O NO NO.
否则,二分最大美丽值,问题就变成了询问是否存在从 s s s 到 t t t 的路径,且这条路径点权的中位数大于等于 m i d mid mid.
在 s s s 到 t t t 的路径中,如果存在两个相邻的点且他们的点权都大于等于 m i d mid mid,那么我们可以在这两个点之间来回走,使得最终路径的中位数大于等于 m i d mid mid.
在 s s s 到 t t t 的路径中,如果不存在两个相邻的点且他们的点权都大于等于 m i d mid mid,那为了使得路径美丽值大于等于 m i d mid mid,最终路径一定是 “点权大于等于 m i d mid mid 的点” 与 “点权小于 m i d mid mid 的点” 交替走,且起点终点的点权不能同时小于 m i d mid mid.
代码实现:
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
typedef double db;
typedef long double ldb;
const int M = (int)2e5;
const int N = (int)2e2;
const ll inf = 0x3f3f3f3f3f3f3f3f;
const double eps = 1e-6;
const ll mod = (ll)998244353;
int n, m, s, t;
int cnt, head[M + 5];
struct enode
{
int v, nx;
} Edge[M * 2 + 5];
int a[M + 5];
bool vis[M + 5];
bool vis2[M + 5];
void init()
{
cnt = 0;
for(int i = 1; i <= n; ++i)
{
head[i] = -1;
vis[i] = 0;
}
}
void add(int u, int v)
{
Edge[cnt].v = v;
Edge[cnt].nx = head[u];
head[u] = cnt++;
}
void dfs1(int u)
{
for(int i = head[u]; ~i; i = Edge[i].nx)
{
int v = Edge[i].v;
if(vis[v]) continue;
vis[v] = 1;
dfs1(v);
}
}
void dfs2(int u, int mid)
{
for(int i = head[u]; ~i; i = Edge[i].nx)
{
int v = Edge[i].v;
if(vis2[v]) continue;
if(a[u] >= mid && a[v] < mid || a[u] < mid && a[v] >= mid)
{
vis2[v] = 1;
dfs2(v, mid);
}
}
}
bool check(int mid)
{
for(int i = 1; i <= n; ++i)
{
if(vis[i] && a[i] >= mid)
{
for(int j = head[i]; ~j; j = Edge[j].nx)
{
if(a[Edge[j].v] >= mid) return 1;
}
}
}
if(a[s] < mid && a[t] < mid) return 0;
for(int i = 1; i <= n; ++i) vis2[i] = 0;
vis2[s] = 1; dfs2(s, mid);
return vis2[t];
}
int read()
{
int x = 0, f = 1;
char ch = getchar();
while(!isdigit(ch))
{
if(ch == '-') f = -1;
ch = getchar();
}
while(isdigit(ch))
{
x = x * 10 + ch - '0';
ch = getchar();
}
return x * f;
}
void work()
{
n = read(); m = read(); s = read(); t = read(); init();
for(int i = 1; i <= n; ++i) a[i] = read();
for(int i = 1, u, v; i <= m; ++i)
{
u = read(); v = read();
add(u, v), add(v, u);
}
vis[s] = 1; dfs1(s);
if(!vis[t]) {
printf("NO\n"); return;}
int l = 1, r = (int)1e9, mid;
while(l < r)
{
mid = (l + r + 1) >> 1;
if(check(mid)) l = mid;
else r = mid - 1;
}
printf("YES\n%d\n", r);
}
int main()
{
// freopen("input.txt", "r", stdin);
// freopen("output.txt", "w", stdout);
int T; scanf("%d", &T);
while(T--) work();
// work();
// cerr << 1.0 * clock() / CLOCKS_PER_SEC << "\n";
return 0;
}
B 比武招亲(上)
题目描述
众所周知,天姐姐只喜欢天下最聪明的人,为了找到这样的人,她决定比武招亲!
只见天姐姐在榜上留下了这样一道问题,谁做出来了就可以俘获她的芳心!
爱慕天姐姐已久的泽鸽鸽问询赶来,只见榜上写着:
给定 n,mn,mn,m,定义一种序列,构造方法如下:
1. 1. 1. 在 [ 1 , n ] [1,n] [1,n] 中任意选择 m m m 次,得到了 m m m 个整数(显然数字可能相同);
2. 2. 2. 将选出的 m m m 个数字排序之后得到一个序列 a 1 , a 2 , . . . , a m {a_1,a_2,...,a_m} a1,a2,...,am。
定义一个序列的贡献为 m a x { a 1 , a 2 , . . . , a m } − m i n { a 1 , a 2 , . . . , a m } max\{a_1,a_2,...,a_m\}−min\{a_1,a_2,...,a_m\} max{ a1,a2,...,am}−min{ a1,a

本文涵盖了多个图论问题的解决方案,包括寻找最短路径、序列构造、树上博弈、石子游戏和树的染色问题。涉及动态规划、二分查找、记忆化搜索、优先队列和并查集等算法。通过对每个问题的详细分析和高效代码实现,展示了如何运用图论知识解决实际问题。
最低0.47元/天 解锁文章
1575

被折叠的 条评论
为什么被折叠?



