Beautiful path and search collection, search, dichotomy

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

Knowledge points :

And search set, search, dichotomy

Ideas :
The first k 2 + 1 \ frac {k } {2} +12k+1 is a small number, that is the median. It should be noted that the question does not say if it is the shortest path, so in order to maximize the beauty value, you can make this path walk repeatedly between two points with large weights.

Then you can find that there are many beauty values, then you can divide the answer into two and find the largest one.

The first is to judge whether there is a connection between the start point and the end point. This can be done by searching or combining.

When it can be connected, two points. Suppose the current beauty value is x, and the beauty value of the path is the point weight of ⌊k/2+1⌋ among the point weights of all points on this path, which is equivalent to that the number of points greater than or equal to x is greater than or equal to all points in the path Half of the point.

In other words, if it is found that the number of points greater than or equal to x is greater than or equal to half of all points in the path, it means that the value of x is smaller at this time, l = m + 1 l=m+1l=m+1 , otherwiser = m − 1 r=m-1r=m1.

How to determine that the number of points greater than or equal to x is greater than or equal to half of all points in the path?

Let the point greater than or equal to x be 1 point, otherwise it is 0 point.

When there are two 1 points in a row, they can go back and forth continuously, which must be greater than half.

Only when 10101010 appears staggered, and the number of 1 is greater than the number of 0, it must be greater than half.

It is easy to find that only when 0101010 appears staggered, and the start point and end point are both 0, it will be less than.

Code :

#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;
}

Guess you like

Origin blog.csdn.net/u011612364/article/details/115031678