7.9校内测T3,克鲁斯卡尔板子题

Posted 57xmz

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了7.9校内测T3,克鲁斯卡尔板子题相关的知识,希望对你有一定的参考价值。

题目背景

lty 看着手机上播放的《Re:从零开始的异世界生活》,心中对ナツキ?スバル?的厌恶值持续增加,对于レム、??的下场十分心痛,看到ナツキ?スバル?ペテルギウス?ロマネコンティ?虐待,心中自然极爽。但男主ナツキ?スバル? 是一个可以复活的奇男子,多次的死亡让他变得越发怠惰。ナツキ?スバル?下定决心,为了让自己活得不那么累,以后连走路也要挑着短的走。

题目描述

一天,ナツキ?スバル? 在无向花园中闲逛,想给エミリア 采几朵花,但是心中的怠惰作祟,决定走一条神奇的道路:

  • 起点为ss
  • 终点为tt
  • 满足在所有的可行道路中,当前所选道路上的最大的边权valval最小

当然,怠惰的ナツキ?スバル? 一点也不想动脑子,想让你在1s1s之内告诉他怎么走,否则他就会加入ペテルギウス?ロマネコンティ? 的队伍,让剧情无法继续发展,限制你能用的内存为256MB256MB,请你帮帮他,来继续恶心lty的同时,让剧情顺利发展。

输入格式

第一行:nn ,mm共两个数,表示图有 nn个顶点,mm条边。

第二至第m+1行:u_iui?v_ivi?w_iwi?共三个数,表示边edge_iedgei?的两个顶点分别是u_iui?v_ivi?,边权为w_iwi?

第m+2行:sstt;共两个数,分别来表示道路的起点和终点

输出格式

一个数valval,表示道路上最大边权的最小值

输入输出样例

输入 #1
4 4
1 2 1
2 4 4
1 3 2
3 4 3
1 4
输出 #1
3

说明/提示

对于5050%的数据,满足 nleq100n100mleq2000m2000wleq100w100

对于 100100%的数据,满足 nleq5000n5000mleq200000m200000wleq1000000w1000000

 

克  鲁  斯  卡  尔  板  子  题

然而我不会(芬芳)

克鲁斯卡尔是一个最小生成树算法,运用贪心策略,找到最小边权和。

代码:

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<cmath>
#define ll long long
using namespace std;
const ll maxn=2e5+10;
ll n,m,s,t;
ll fa[maxn],eu,ev,ans,cnt;
inline ll read()
{
    ll x=0,f=1;char ch=getchar();
    while (!isdigit(ch)){if (ch==-) f=-1;ch=getchar();}
    while (isdigit(ch)){x=x*10+ch-48;ch=getchar();}
    return x*f;
}
struct node
{
    ll u,v,w;
} edge[maxn];
inline int find(ll x)
{
    if(fa[x]==x) return x;
    return fa[x]=find(fa[x]);//找根节点? 
}
inline bool cmp(node a,node b)
{
    return a.w<b.w;
}//贪心思想,按边权排序,先连边权小的边 
inline void kruskal()
{
    sort(edge+1,edge+m+1,cmp); 
    for(int i=1;i<=m;i++)
    {
        eu=find(edge[i].u),ev=find(edge[i].v);//u是这条边的起点,v是这条边的终点 
        if(eu==ev) continue;//如果它们在一个集合里,那么不能连边 
        ans+=edge[i].w;//总长度加上边权 
        fa[ev]=eu;//合并祖先 (ev和eu倒过来没有影响) 
        cnt++;//边数++ 
        if(find(s)==find(t))//如果起点和终点已经在一个集合里了,那么输出 
        {
            printf("%lld
",edge[i].w);//因为我们是按边权排序之后逐渐加边,那么我们每次加的边一定比后来加的边边权小,本题要求的是路径中最大值最小,所以不用再往后找了,直接输出即可 
            return;
        }
        if(cnt==(n-1)) break;//如果边数==n-1,那说明已经把所有的点全部连起来了,直接break 
    }
}
int main()
{
    scanf("%lld%lld",&n,&m);
    for(int i=1;i<=n;i++) fa[i]=i;
    for(int i=1;i<=m;i++)
    {
        scanf("%lld%lld%lld",&edge[i].u,&edge[i].v,&edge[i].w);
    }
    s=read();
    t=read();
    kruskal();
    return 0;
}

 

题目背景

lty 看着手机上播放的《Re:从零开始的异世界生活》,心中对ナツキ?スバル?的厌恶值持续增加,对于レム、??的下场十分心痛,看到ナツキ?スバル?ペテルギウス?ロマネコンティ?虐待,心中自然极爽。但男主ナツキ?スバル? 是一个可以复活的奇男子,多次的死亡让他变得越发怠惰。ナツキ?スバル?下定决心,为了让自己活得不那么累,以后连走路也要挑着短的走。

题目描述

一天,ナツキ?スバル? 在无向花园中闲逛,想给エミリア 采几朵花,但是心中的怠惰作祟,决定走一条神奇的道路:

  • 起点为ss
  • 终点为tt
  • 满足在所有的可行道路中,当前所选道路上的最大的边权valval最小

当然,怠惰的ナツキ?スバル? 一点也不想动脑子,想让你在1s1s之内告诉他怎么走,否则他就会加入ペテルギウス?ロマネコンティ? 的队伍,让剧情无法继续发展,限制你能用的内存为256MB256MB,请你帮帮他,来继续恶心lty的同时,让剧情顺利发展。

输入格式

第一行:nn ,mm共两个数,表示图有 nn个顶点,mm条边。

第二至第m+1行:u_iui?v_ivi?w_iwi?共三个数,表示边edge_iedgei?的两个顶点分别是u_iui?v_ivi?,边权为w_iwi?

第m+2行:sstt;共两个数,分别来表示道路的起点和终点

输出格式

一个数valval,表示道路上最大边权的最小值

输入输出样例

输入 #1
4 4
1 2 1
2 4 4
1 3 2
3 4 3
1 4
输出 #1
3

说明/提示

对于5050%的数据,满足 nleq100n100mleq2000m2000wleq100w100

对于 100100%的数据,满足 nleq5000n5000mleq200000m200000wleq1000000w1000000

以上是关于7.9校内测T3,克鲁斯卡尔板子题的主要内容,如果未能解决你的问题,请参考以下文章

克鲁斯卡尔算法

4.10 模拟赛 最小生成树 克鲁斯卡尔思想 优化建图

(王道408考研数据结构)第六章图-第四节2:最小生成树之克鲁斯卡尔算法(思想代码演示答题规范)

克鲁斯卡尔算法是怎样判断是不是构成了回路

最小生成树 普里姆算法和克鲁斯卡尔算法

克鲁斯卡尔算法 判断回路中的问题