zoukankan      html  css  js  c++  java
  • 7.9校内测T3,克鲁斯卡尔板子题

    题目背景

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

    题目描述

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

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

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

    输入格式

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

    第二至第m+1行:u_iuiv_iviw_iwi共三个数,表示边edge_iedgei的两个顶点分别是u_iuiv_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;
    }
  • 相关阅读:
    spring框架基本操作
    HTML 小练习(静态网页)
    sqldeveloper 连接oracle失败报12514(日常错误)
    基于docker容器搭建fastdfs分布式文件系统
    centos7 64位系统jdbc连接oracle报错问题
    openstack kolla多节点容器化环境安装
    Android TabHost设置setCurrentTab(index),当index!=0时,默认加载第一个tab问题解决方法。
    maven导入dom4j以及jaxen.jar报java.lang.UnsupportedOperationException:错误
    android自学笔记(1):android简介
    Linux命令(7):rm命令
  • 原文地址:https://www.cnblogs.com/57xmz/p/13278473.html
Copyright © 2011-2022 走看看