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

看到连最少的边,第一时间会想到 \(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. 本地Redis服务配置

    本地Redis服务配置 要求:在虚拟机中启动redis服务,并要在windows物理机上取得链接 虚拟机安装略,(结果如下) windows工作机上装了Oracle VM VirtualBox,并在其 ...

  2. 关于C#设计SQllite

    使用3.5框架+System.Data.SQLite,System.Data.SQLite.Ling+SQLite.Designer三个dll

  3. Spring 事件(2)- 自定义事件

    Spring 系列教程 Spring 框架介绍 Spring 框架模块 Spring开发环境搭建(Eclipse) 创建一个简单的Spring应用 Spring 控制反转容器(Inversion of ...

  4. Ubantu学习笔记3

    修改PATH环境变量 ~/.profile --->(在文件最后一行添加) PATH="要增加的路径:$PATH" 或者 export 使用变量="调用参数&quo ...

  5. P 1025 链表反转

    转跳点:

  6. 读书笔记 - js高级程序设计 - 第八章 BOM

      BOM的核心对象是window 它表示浏览器的一个实例,在浏览器中,window对象有双重角色,它既是通过js访问浏览器窗口的一个接口,又是ECMAScript规定的Global对象,这意味着在网 ...

  7. Express ~ 获取表单 get 和 post 提交方式传送参数的对比

      一,获取 get 提交的参数   var id = req.query.id || ''   二,获取 post 提交的参数 var name = req.body.name || ''

  8. tableau中图形分析相关设置

    1.柱形堆叠图单元格顶部显示总计值(可通过参考线实现) 2.调节图形单元格的宽窄度 (ctrl + 右键/左键) 3.折线图预测区间 趋势区间线 分析中预测并不是针对所有的日期格式均其作用,比如日期格 ...

  9. bne 1b 汇编含义

    汇编指令中 bne label 这条指令有以下两种特别的写法:bne 1b, bne 1f. bne 1b 指的是 backward,倒退寻找标号为 1 的地方并跳转. 同样也有 bne 1f,值得是 ...

  10. Sqlserver 增删改查----删

    --我们就以院系,班级,学生来举例. create TABLE [dbo].YuanXi ( Id ,) NOT NULL,--学校id 自增量 YuanXiName varchar() null, ...