zoukankan      html  css  js  c++  java
  • 【bzoj1050】 旅行comf

    http://www.lydsy.com/JudgeOnline/problem.php?id=1050 (题目链接)

    题意

      给出一个无向图,求图中两点间某条路径使得最大权值除以最小权值的值最小

    Solution

      今天考试题,写了个萎的dijistra,30分。。。

      正解是滑动窗口+最小生成树(其实并不是最小)。我们想让路径中最大的边和最小的边相差尽可能小,也就是说将边按权值从小到大排序后,路径就是序列中连续的一段所组成的生成树。枚举生成树中最小的边,然后往树中加边。当s与t联通时就break,更新答案。复杂度m²。

    代码

    // bzoj1050
    #include<algorithm>
    #include<iostream>
    #include<cstdlib>
    #include<cstring>
    #include<cstdio>
    #include<cmath>
    #include<queue>
    #define LL long long
    #define inf 2147483640
    #define Pi acos(-1.0)
    #define free(a) freopen(a".in","r",stdin),freopen(a".out","w",stdout);
    using namespace std;
    inline LL getint() {
        int f,x=0;char ch=getchar();
        while (ch<='0' || ch>'9') {if (ch=='-') f=-1;else f=1;ch=getchar();}
        while (ch>='0' && ch<='9') {x=x*10+ch-'0';ch=getchar();}
        return x*f;
    }
    
    const int maxn=5010;
    struct edge {int u,v,w;}e[maxn];
    int fa[maxn],n,m,s,t;
    
    bool cmp(edge a,edge b) {
        return a.w<b.w;
    }
    int gcd(int x,int y) {
        return x%y==0?y:gcd(y,x%y);
    }
    int find(int x) {
        return x==fa[x] ? x : fa[x]=find(fa[x]);
    }
    int main() {
        scanf("%d%d",&n,&m);
        for (int i=1;i<=m;i++) scanf("%d%d%d",&e[i].u,&e[i].v,&e[i].w);
        sort(e+1,e+1+m,cmp);
        scanf("%d%d",&s,&t);
        int x1=-1,y1=-1;
        for (int i=1;i<=m;i++) {
            if (e[i].w==e[i-1].w) continue; //质的飞越,快的不只一点点
            for (int j=1;j<=n;j++) fa[j]=j;
            for (int j=i;j<=m;j++) {
                int r1=find(e[j].u),r2=find(e[j].v);
                if (r1!=r2) fa[r1]=r2;
                if (find(s)==find(t)) {
                    if (y1==-1 || (double)x1/y1>(double)e[j].w/e[i].w) x1=e[j].w,y1=e[i].w;
                    break;
                }
            }
            if (y1==-1) {printf("IMPOSSIBLE");return 0;}
        }
        int x=gcd(x1,y1);
        x1/=x,y1/=x;
        if (y1==1) printf("%d
    ",x1);
        else printf("%d/%d
    ",x1,y1);
        return 0;
    }
    

      

  • 相关阅读:
    看Web视频整理标签笔记
    公文流转系统进度
    文件和流课堂实验三
    文件和流课堂实验二
    2018/10/21动手动脑
    第二次实验报告动手动脑
    2018.10.11上课进度说明
    原码反码补码
    课上动手动脑总结
    Java实验一——习题册+登陆界面 总结
  • 原文地址:https://www.cnblogs.com/MashiroSky/p/5914193.html
Copyright © 2011-2022 走看看