Hermoso camino y búsqueda, búsqueda, dicotomía

Enlace : https://ac.nowcoder.com/acm/contest/9985/A

Puntos de conocimiento :

Y conjunto de búsqueda, búsqueda, dicotomía

Ideas :
los primeros k 2 + 1 \ frac {k } {2} +12k+1 es un número pequeño, que es la mediana. Cabe señalar que la pregunta no dice si es el camino más corto, por lo que para maximizar el valor de belleza, puede hacer que este camino camine repetidamente entre dos puntos con pesos grandes. .

Luego puede encontrar que hay muchos valores de belleza, luego puede dividir la respuesta en dos y encontrar el más grande.

La primera es juzgar si existe una conexión entre el punto de inicio y el punto final, lo que se puede hacer buscando o combinando.

Cuando se puede conectar, dos puntos. Suponga que el valor de belleza actual es x, y el valor de belleza de la ruta es el peso puntual de ⌊k / 2 + 1⌋ entre las ponderaciones puntuales de todos los puntos de esta ruta, que es equivalente al número de puntos mayor que o igual ax es mayor o igual que todos los puntos de la ruta Mitad del punto.

En otras palabras, si se encuentra que el número de puntos mayor o igual que x es mayor o igual a la mitad de todos los puntos en la ruta, significa que el valor de x es menor en este momento, l = m + 1 l = m + 1l=metro+1 , de lo contrarior = m - 1 r = m-1r=metro-1 .

¿Cómo determinar que el número de puntos mayor o igual ax es mayor o igual a la mitad de todos los puntos en la ruta?

Deje que el punto mayor o igual ax sea 1 punto, de lo contrario es 0 punto.

Cuando hay dos puntos 1 seguidos, pueden ir y venir continuamente, lo que debe ser mayor que la mitad.

Solo cuando 10101010 aparece escalonado y el número 1 es mayor que el número 0, debe ser mayor que la mitad.

Es fácil encontrar que solo cuando 0101010 aparece escalonado y el punto de inicio y el punto final son ambos 0, será menor que.

Codigo :

#include <bits/stdc++.h>
#include <iostream>
using namespace std;
const int maxn = 200005;
typedef long long ll;

int a[maxn];
int vis[maxn];
int fa[maxn];

vector<int> g[maxn];
int T,n,m,s,t;
int ans =0;
bool flag = false;

int find(int x){
    
    
    return fa[x] == x ? x : fa[x] = find(fa[x]); 
}
void dfs(int u,int x)
{
    
    
    vis[u] = 1;
    for(auto v : g[u]){
    
    
        if(a[u] >= x && a[v] >= x)
            flag = true;
        if(!vis[v])
            dfs(v,x);
    }
}

void dfs2(int u,int x)
{
    
    
    vis[u] = 1;
    for(auto v : g[u]){
    
    
        if(!vis[v] && (a[u] >= x) != (a[v] >= x))
            dfs2(v,x);
    }
}

int check(int x){
    
    
    memset(vis,0,sizeof(vis));
    flag = false;
    dfs(s,x);
    if(flag)
        return 1;
    if(a[s] < x && a[t] < x)
        return false;
    memset(vis,0,sizeof(vis));
    dfs2(s,x);
    if(vis[t] == 1)
        return 1;
    else
        return 0;
}

int main()
{
    
    
    cin.tie(0);
    ios::sync_with_stdio(false);
    cin>>T;
    while(T--){
    
    
        cin>>n>>m>>s>>t;
        for(int i = 1;i <= n;i++){
    
    
            g[i].clear();
            fa[i] = i;
            cin>>a[i];
        }
        int u,v;
        for(int i = 1;i <= m;i++){
    
    
            cin>>u>>v;
            g[u].push_back(v);
            g[v].push_back(u);
            fa[find(u)] = find(v);
        }
        if(find(s) == find(t)){
    
    
            cout<<"YES"<<endl;
            int l = 1,r = 1e9;
            while( l <= r){
    
    
                int m = (l + r) >> 1;
                if(check(m))
                    l = m + 1;
                else
                    r = m - 1;
            }
            cout<<r<<endl;
        }
        else
            cout<<"NO"<<endl;
    }
    return 0;
}

Supongo que te gusta

Origin blog.csdn.net/u011612364/article/details/115031678
Recomendado
Clasificación