• Nowcoder9985A.美丽的路径(二分答案)


    A.美丽的路径

    题意:

    给出一个n*m的无向图,每个点有点权。

    定义一条路径的美丽值是这条路径上第[k/2+1]小的点权。

    询问是否存在从起点s到终点t的路径,如果存在则输出YES,再输出所有路径的最大美丽值。

    如果不存在输出NO。

    题解:

    考虑二分答案。

    假设当前二分的值是k。把所有比k大的点设为1点,把所有比k小的点设为0点。

    当两个1点相邻的时候,可以通过在这两个点之间来回走,达到提升美丽值的效果,这种情况直接return 1。

    不存在两个1点相邻的时候,查看起点到终点是否存在1010101...或010101..,即01必须交错,因为没有两个1相邻了,如果存在001..必然会导致1的数量不够,美丽值达不到要求。

    这一步大力DFS一下就行了。

    // Problem: 美丽的路径
    // Contest: NowCoder
    // URL: https://ac.nowcoder.com/acm/contest/9985/A
    // Memory Limit: 524288 MB
    // Time Limit: 6000 ms
    // 
    // Powered by CP Editor (https://cpeditor.org)
    
    //s到t有路径
    //考虑二分答案
    //大于等于k的点设为1
    //小于k的点设为0
    //当有两个1的点之间有边的时候,直接return 1
    //否则从起点出发,0101010..或者101010..因为没有两个1相连
    //所以必须01交错
    
    #include<bits/stdc++.h>
    using namespace std;
    const int maxn=2e5+100;
    int n,m,s,t,_,a[maxn];
    vector<int> g[maxn];
    int vis[maxn];
    int f;
    void dfs (int x) {
    	vis[x]=1;
    	for (int y:g[x]) {
    		if (vis[y]) continue;
    		dfs(y);
    	}
    }
    void dfs1 (int x,int k) {
    	vis[x]=1;
    	for (int y:g[x]) {
    		if (a[x]>=k&&a[y]>=k) f=1;
    		if (vis[y]) continue;
    		dfs1(y,k);
    	}
    }
    void dfs2 (int x,int k,int ff) {
    	vis[x]=1;
    	for (int y:g[x]) {
    		if (vis[y]) continue;
    		if ((a[y]>=k)^ff) dfs2(y,k,!ff);
    	}
    } 
    int check (int k) {
    	for (int i=1;i<=n;i++) vis[i]=0;f=0;
    	dfs1(s,k);
    	if (f==1) return 1;
    	for (int i=1;i<=n;i++) vis[i]=0;
    	dfs2(s,k,a[s]>=k);
    	if (vis[t]) return 1;
    	return 0;
    }
    int main () {
    	scanf("%d",&_);
    	while (_--) {
    		scanf("%d%d%d%d",&n,&m,&s,&t);
    		for (int i=1;i<=n;i++) scanf("%d",a+i);
    		for (int i=1;i<=n;i++) g[i].clear();
    		for (int i=1;i<=m;i++) {
    			int x,y;
    			scanf("%d%d",&x,&y);
    			g[x].push_back(y);
    			g[y].push_back(x);
    		}
    		for (int i=1;i<=n;i++) {
    			vis[i]=0;
    		}
    		dfs(s);
    		if (!vis[t]) {
    			printf("NO
    ");
    			continue;
    		}
    		int l=1,r=1e9;
    		int ans=0;
    		while (l<=r) {
    			int mid=(l+r)>>1;
    			if (check(mid)) {
    				l=mid+1;
    				ans=mid;
    			}
    			else {
    				r=mid-1;
    			}
    		}
    		printf("YES
    %d
    ",ans);
    	}
    }
    
  • 相关阅读:
    Golang Channel用法简编
    一个有关Golang变量作用域的坑
    Goroutine是如何工作的
    Go语言是如何处理栈的
    Go与C语言的互操作
    Lua虚拟机初始化
    lua 函数调用 -- 闭包详解和C调用
    c++对象导出到lua
    nginx缓存设置proxy_cache
    golang中map并发读写问题及解决方法
  • 原文地址:https://www.cnblogs.com/zhanglichen/p/14532745.html
Copyright © 2020-2023  润新知