zoukankan      html  css  js  c++  java
  • 【USACO 2020 January Silver】Wormhole Sort 题解

    题目描述
    Farmer John 的奶牛们已经厌倦了他对她们每天早上排好序离开牛棚的要求。她们刚刚完成了量子物理学的博士学位,准备将这一过程搞快点。
    今天早上,如同往常一样,Farmer John 的 N 头编号为 1…N 的奶牛(1≤N≤10^5),分散在牛棚中 N 个编号为 1…N 的不同位置,奶牛 i 位于位置 pi。但是今天早上还出现了 M 个编号为 1…M 的虫洞(1≤M≤10^5),其中虫洞 i 双向连接了位置 ai 和 bi,宽度为 wi(1≤ai,bi≤N,ai≠bi,1≤wi≤10^9)。
    在任何时刻,两头位于一个虫洞两端的奶牛可以选择通过虫洞交换位置。奶牛们需要反复进行这样的交换,直到对于 1≤i≤N,奶牛 i 位于位置 i。
    奶牛们不想被虫洞挤坏。帮助她们最大化被她们用来排序的虫洞宽度的最小值。保证奶牛们有可能排好序。

    输入
    输入的第一行包含两个整数 N 和 M。
    第二行包含 N 个整数 p1,p2,…,pN。保证 p 是 1…N 的一个排列。
    对于 1 到 M 之间的每一个 i,第 i+2 行包含整数 ai、bi 和 wi。

    输出
    输出一个整数,为在排序过程中奶牛必须挤进的虫洞的最小宽度的最大值。如果奶牛们不需要用任何虫洞来排序,输出 −1。

    样例输入
    4 4
    3 2 1 4
    1 2 9
    1 3 7
    2 3 10
    2 4 3

    样例输出
    9

    数据范围限制
    测试点 1-5 满足 N,M≤1000。
    测试点 6-10 没有额外限制。

    提示
    ​以下是一个仅用宽度至少为 9 的虫洞给奶牛排序的可能方案:
    奶牛 1 和奶牛 2 使用第三个虫洞交换位置。
    奶牛 1 和奶牛 3 使用第一个虫洞交换位置。
    奶牛 2 和奶牛 3 使用第三个虫洞交换位置。

    铺垫:

    1. 并查集两个标准函数:
    int find(int x){    //递归找x的祖先。
    	if(father[x]!=x) father[x]=find(father[x]);
    	return father[x];
    }
    void hb(int x,int y){   //合并x,y结点。
    	int a=find(x);
    	int b=find(y);
    	if(a!=b){
    		father[a]=b;
    	}
    }
    

    2.如果判断一个并查集,是否成立:
    细心观察会发现,第i个点走到 p[i]可以转化为点i和点 p[i] 连通.

    		for(int i=1;i<=n;i++){
    			if(find(i)!=find(w[i])){
    				bz=1;
    				break;
    			}
    		}
    

    思路:

    由题容易知道答案一定是所给虫洞中的某一个,我们可以先假设最大的最小虫洞大小为mod,之后遍历宽度大于等于mod虫洞,将虫洞连接的两个点并入并查集,最后再检查这个集合是否成立。

    最暴力的方法是从最大的mod开始找,一直找到成立为止,但这是O(NM)的算法,一定会超时,那就要换个思路

    由于mod一定是所给虫洞中的某一个,于是不难会想到二分思路,O(log(n)*m),不会超时。

  • 相关阅读:
    normalize.css 中文版
    [转载]自适应高度输入框
    【转载】H5页面列表的无线滚动加载(前端分页)
    CSS设置table下tbody滚动条与thead对齐的方法
    [转载]Jquery mobiscroll 移动设备(手机)wap日期时间选择插件以及滑动、滚动插件
    wordpress 目录、数据结构和解析原理
    WordPress基础知识:条件判断标签及用法大全
    主题如何添加tag标签页面
    WordPress进阶:[2]不同页面显示不同的侧边栏
    WordPress进阶:[1]怎样用tag标签做导航菜单
  • 原文地址:https://www.cnblogs.com/2020-zhy-jzoj/p/13159902.html
Copyright © 2011-2022 走看看