这题真的是非常标准的模板题啊

看到连最少的边,第一时间会想到 \(kruskal\) .这道题的难点其实就一个:你要注意到连边权最大的边使整个图联通

为什么:题意是第i个点想走到 \(pos[i]\) ,也就是说点i和点 \(pos[i]\) 必须要联通.

为什么想不到 \(kruskal\) :因为 \(kruskal\) 是最小生成树,比较难想到两条边权大的边连起来并不会影响最小权值.

扯远了进入正题:

1.怎么保证连的边的权值最大:

将边权从大到小排列,需要拿的边尽量拿(因为并不会影响最小权值).

2.怎么查两点是否连通:

这个是 \(kruskal\) 算法最基本的要领.如果一个点的父亲 \(fat[i]\) 等于另外一个点的父亲 \(fat[j]\), 那么我们可以确定这两点连通

3.要连什么点

细心观察会发现,第i个点走到 \(pos[i]\) 可以转化为点i和点 \(pos[i]\) 连通.

4.怎么判断什么时候全图连通:

因为要求是一定要全部连通才行,所以如果有一个点不连通,后面怎么连通都没用.而如果有一个点连通了,就算后面再怎么连,最后这个点仍然连通.所以,我们可以做一个指针.指针从1开始,表示第一个不连通的点.每次连边之前先确定还有哪条边不连通.如果我们发现连通的点数已经大于总的点数,那么答案就是输出了

上代码:(124ms吊打目前所有解法)

#include <iostream>
#include <algorithm> using namespace std;
inline int read() {
int x=0,w=1;
char ch;
while(ch<'0'||ch>'9')
{
if(ch=='-')
w=-1;
ch=getchar();
}
while(ch>='0'&&ch<='9')
x=(x<<3)+(x<<1)+ch-'0',ch=getchar();
return x*w;
}
int n,m,pos[100005],tot = 0,fat[100005], ans = -1;
struct Edge{
int from,to,dis;
}edge[300005];
int father(int x){
while(x!=fat[x]) x=fat[x]=fat[fat[x]];//这个是kruskal的一个加速方法,在查自己的时候可以直接更新父亲
return x;
}
void Union(int x, int y){
fat[father(y)] = father(x);
}
void add(int f, int t, int d){
edge[++tot].from = f;
edge[tot].to = t;
edge[tot].dis = d;
}
//不解释
bool sorted(Edge a, Edge b){
return a.dis>b.dis;//从大到小排列
}
int main(){
n = read();m = read();
for (int i=1;i<=n;i++) pos[i] = read();
for (int i=0;i<m;i++){
int a,b,c;
a = read();b = read(); c = read();
add(a,b,c);//连边
}
sort(edge+1,edge+tot+1,sorted);//从大到小排列
int ptr = 1;
for (int i=1;i<=n;i++) fat[i] = i;//自己爸爸一开始就是自己
for (int i=1;i<=tot;i++){
while(father(ptr)==father(pos[ptr])) {ptr++; if (ptr>n) goto abcd;}//当我爸跟他爸是同一个人就增加,直到我跟他都不存在或者我爸不是他爸
if (father(pos[edge[i].from])!=father(pos[edge[i].to])){
Union(pos[edge[i].from],pos[edge[i].to]);//如果他爸不是我爸,那我将我爸设成他爸
ans = edge[i].dis;//答案就是现在的边权
}
}
abcd:;
printf("%d",ans);
}

题解 P6004 【[USACO20JAN]Wormhole Sort S】的更多相关文章

  1. 算法与数据结构基础 - 排序(Sort)

    排序基础 排序方法分两大类,一类是比较排序,快速排序(Quick Sort).归并排序(Merge Sort).插入排序(Insertion Sort).选择排序(Selection Sort).希尔 ...

  2. poj2785双向搜索

    The SUM problem can be formulated as follows: given four lists A, B, C, D of integer values, compute ...

  3. LeetCode Minimum Time Difference

    原题链接在这里:https://leetcode.com/problems/minimum-time-difference/description/ 题目: Given a list of 24-ho ...

  4. LeetCode Relative Ranks

    原题链接在这里:https://leetcode.com/problems/relative-ranks/#/description 题目: Given scores of N athletes, f ...

  5. 华中农业大学第四届程序设计大赛网络同步赛 J

    Problem J: Arithmetic Sequence Time Limit: 1 Sec  Memory Limit: 128 MBSubmit: 1766  Solved: 299[Subm ...

  6. [BZOJ3555] [Ctsc2014]企鹅QQ(Hash)

    传送门 可以枚举被删除的位置,然后用hash表判重,然而网上好多题解都是用 sort 判重的. 不知道为什么,int 总是过不了,换成 long long 或者是 unsigned long long ...

  7. Codefoces 828C

    C. String Reconstruction time limit per test 2 seconds memory limit per test 256 megabytes input sta ...

  8. 算法与数据结构基础 - 广度优先搜索(BFS)

    BFS基础 广度优先搜索(Breadth First Search)用于按离始节点距离.由近到远渐次访问图的节点,可视化BFS 通常使用队列(queue)结构模拟BFS过程,关于queue见:算法与数 ...

  9. CF - 1108 F MST Unification

    题目传送门 题意:在一幅图中, 问需要使得多少条边加一,使得最小生成树只有一种方案. 题解:Kruskal, sort完之后,对于相通的一个边权w,我们可以分析出来有多少边是可以被放到图里面的,然后我 ...

随机推荐

  1. LCT(1)

    LCT(Link-Cut Tree,动态树)是一个支持动态修改树的结构的数据结构,其基本操作有 \(\texttt{access}\) , \(\texttt{findroot}\) , \(\tex ...

  2. jqGrid 添加 合计行 footDate

    jQuery(table_id).jqGrid({ url : url,//组件创建完成之后请求数据的url datatype : "json",//请求数据返回的类型.可选jso ...

  3. bool之regexp正则注入(原理详解)

    感谢原创博主的文章,在此致敬.本文转自:http://www.cnblogs.com/lcamry/articles/5717442.html 我们都已经知道,在MYSQL 5+中 informati ...

  4. ios 进阶技术点

    1.Runtime的消息转发机制 消息转发机制基本上分为三个步骤: 1. 动态方法解析 2. 备用接收者 3. 完整转发 2.Runloop的工作原理 runloop.autorelease pool ...

  5. 全面掌握Nginx配置+快速搭建高可用架构 一 Nginx的访问控制

    语法 示例 allow 127.0.0.1; deny all; 缺点:局限性 如果通过代理就可以绕过访问限制,限制不准确 解决 1. http_x_forwarded_for 2. 结合geo模块作 ...

  6. Swift字符串截取与Range使用

    1.String.Index String.Index表示一个位置,使用String与String.Index可以获取该位置的Character let str = "123456789&q ...

  7. 体验京东云 Serverless+AI 人脸属性识别

    云原生计算基金会CNCF(Cloud Native Computing Foundation, CNCF)Serverless Whitepaper v1.0对无服务器计算作了如下定义: Server ...

  8. 吴裕雄--天生自然C++语言学习笔记:C++ 存储类

    存储类定义 C++ 程序中变量/函数的范围(可见性)和生命周期.这些说明符放置在它们所修饰的类型之前.下面列出 C++ 程序中可用的存储类: auto register static extern m ...

  9. Linux学习-第二章(命令)20200216

  10. Sequence Models Week 1 Character level language model - Dinosaurus land

    Character level language model - Dinosaurus land Welcome to Dinosaurus Island! 65 million years ago, ...