zoukankan      html  css  js  c++  java
  • 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);
    	}
    }
    
  • 相关阅读:
    当初为蜂巢样式实验过的方法
    在看 jquery 源码中发现的一些优化方向
    我终于有案例库啦(github 提供的)
    学习笔记(五)
    试坑不完美的 clip-path (我说的 CSS 的那个)
    解决安卓机在微信上播放视频有广告问题
    requestAnimationFrame 的实验性实践
    学习笔记(四)
    ajax
    php 增删改查---增
  • 原文地址:https://www.cnblogs.com/zhanglichen/p/14532745.html
Copyright © 2011-2022 走看看