zoukankan      html  css  js  c++  java
  • BZOJ 1050: [HAOI2006]旅行comf (并查集 或 单调队列)

    这是建空间后做的第一道题啊= =好水

    排序,枚举最小边,然后并查集求出联通时的最大边

    或者排次序,从小到大插边,如果插边时最小的边拿掉不会使s与t不联通,就删去。

    code:

    #include<cstdio>
    #include<iostream>
    #include<algorithm>
    #include<cstring>
    using namespace std;
    struct node{
        int x,y,dist;
    }a[5010];
    int n,m,s,t,f[510],ansi,ansa;
    bool cmp(node x,node y){return x.dist<y.dist;}
    int find(int x){if (x!=f[x]) f[x]=find(f[x]);return (f[x]);}
    int gcd(int x,int y){
        if (!y) return x;
        return gcd(y,x %y);
    }
    int main(){
        scanf("%d%d",&n,&m);
        for (int i=1;i<=m;i++) scanf("%d%d%d",&a[i].x,&a[i].y,&a[i].dist);
        sort(a+1,a+1+m,cmp);
        scanf("%d%d",&s,&t);
        ansi=a[1].dist;ansa=40000;
        for (int i=1;i<=n;i++) f[i]=i;
        for (int i=1;i<=m;i++) {
            int x=find(a[i].x),y=find(a[i].y);
            if (x!=y) f[x]=y;
            x=find(s);y=find(t);
            if (x==y) {
                ansa=a[i].dist;
                break;
            }
        }
        if (ansa==40000) {printf("IMPOSSIBLE ");return 0;}
        for (int i=2;i<=m;i++) {
            for (int j=1;j<=n;j++) f[j]=j;
            for (int j=i;j<=m;j++) {
                int x=find(a[j].x),y=find(a[j].y);
                if (x!=y) f[x]=y;
                x=find(s);y=find(t);
                if (x==y) {
                    if (ansa*1.0/ansi>a[j].dist*1.0/a[i].dist) {ansa=a[j].dist;ansi=a[i].dist;}
                    break;
                }
            }
        }
        int t=gcd(ansa,ansi);
        if (ansa*1.0/ansi==ansa/ansi) printf("%d ",ansa/ansi);
        else printf("%d/%d",ansa/t,ansi/t);
        return 0;
    }
  • 相关阅读:
    字符串中的不可见字符应该如何清除?
    字符/字段数据的合并
    分割字符串的应用
    几种分割字符串实现方法的比较
    linux的一些文件基本命令
    centos7安装es6.4.0
    Sql 语句中 IN 和 EXISTS 的区别及应用
    Springboot通过redisTemplate实现发布订阅
    代理模式
    单例模式的多种实现方法
  • 原文地址:https://www.cnblogs.com/New-Godess/p/4348966.html
Copyright © 2011-2022 走看看