• CSUOJ 1651 Weirdo


    1651: Weirdo

    Time Limit: 5 Sec  Memory Limit: 128 MB
    Submit: 40  Solved: 21
    [Submit][Status][Web Board]

    Description

    小x是一个奇葩,奇葩的小x终于盼来了五一长。。好吧!短假。早已乏味的大学生活让小x感到绝望。与其天天做在电脑面前废寝忘食的打LOL,还不如来一场说走就走的旅行,去看看外面的世界!已经准备去往B市的小x决定让自己的旅行更有意义一点,他觉得人生本就是一场漫长的旅行,重要的不是终点,而是奇葩的路线。他决定找一条通往B市的最均匀的路线!什么样的路线最呀最均匀?当然是这条线路上的路段之间的宽度差的绝对值最小的那条就均匀啦!现在给出n个城市和m条道路及这m条道路的路宽,并且保证居住在A市的小x是可以到达B市,你能帮助小x找出这样的最均匀的路线么,输出这条路线上的最大差值!

    Input

    每个样例的第一行n,m,A,B分别表示有n个点,m条路段,小x的居住地和小x要到的B市,接下来m行,每行三个数字u,v,w分别表示从u到v的这段路的路宽(路是双向的)。 
    2 <= n <= 1500, 
    m <= 3000, 
    0 <= v,u < n, 
    w < INT_MAX

    Output

    每个样例输出一行

    Sample Input

    5 5 4 0
    0 3 22022
    1 2 8871
    1 3 9421
    2 4 24398
    3 4 3344

    Sample Output

    15527

    HINT

     

    Source

    解题:直接枚举下界,求最小上界用类似于最小生成树Kruskal的做法

     1 #include <iostream>
     2 #include <cstdio>
     3 #include <algorithm>
     4 using namespace std;
     5 typedef long long LL;
     6 const int maxn = 40001;
     7 const int INF = 0x3f3f3f3f;
     8 struct arc{
     9     int u,v,w;
    10     bool operator<(const arc &t) const{
    11         return w < t.w;
    12     }
    13 }e[maxn];
    14 int uf[maxn],n,m,S,T,ret;
    15 bool flag;
    16 int Find(int x){
    17     int t = x;
    18     while(uf[x] != x) x = uf[x];
    19     while(uf[t] != t){
    20         int tmp = uf[t];
    21         uf[t] = x;
    22         t = tmp;
    23     }
    24     return x;
    25 }
    26 int kruskal(int low){
    27     for(int i = 0; i <= n; ++i) uf[i] = i;
    28     for(int i = low; i < m; ++i){
    29         int x = Find(e[i].u);
    30         int y = Find(e[i].v);
    31         if(x == y) continue;
    32         uf[x] = y;
    33         if(Find(S) == Find(T)) return e[i].w - e[low].w;
    34         if((LL)e[low].w + ret <= e[i].w) return INF;
    35     }
    36     flag = false;
    37     return INF;
    38 }
    39 int main(){
    40     //freopen("Weirdo.in","r",stdin);
    41     //freopen("oo.txt","w",stdout);
    42     while(~scanf("%d %d %d %d",&n,&m,&S,&T)){
    43         for(int i = 0; i < m; ++i)
    44             scanf("%d %d %d",&e[i].u,&e[i].v,&e[i].w);
    45         sort(e,e+m);
    46         ret = INF;
    47         flag = true;
    48         for(int i = 0; i < m && flag; ++i)
    49             ret = min(kruskal(i),ret);
    50         printf("%d
    ",ret);
    51     }
    52     return 0;
    53 }
    View Code
  • 相关阅读:
    将一个全是字母的字符串转化为大写
    将一个全是字母,以0结尾的字符串,转化为大写
    call指令和ret指令的配合使用
    将一个全是字母,以0结尾的字符串,转化为大写
    《那些年啊,那些事——一个程序员的奋斗史》——45
    《那些年啊,那些事——一个程序员的奋斗史》——46
    《那些年啊,那些事——一个程序员的奋斗史》——44
    《那些年啊,那些事——一个程序员的奋斗史》——44
    《那些年啊,那些事——一个程序员的奋斗史》——44
    《那些年啊,那些事——一个程序员的奋斗史》——43
  • 原文地址:https://www.cnblogs.com/crackpotisback/p/4547889.html
Copyright © 2020-2023  润新知