• bzoj 1050 旅行comf


    题目大意:

    一个无向图,N(N<=500)个顶点, M(M<=5000)条边,每条边有一个权值Vi(Vi<30000)

    两个顶点S和T,求一条路径,使得路径上最大边和最小边的比值最小

    如果S和T之间没有路径,输出”IMPOSSIBLE” 否则输出这个比值(最简)

    思路:

    我们可以枚举所有边的下限

    先按边权排序

    然后从这条边开始向上枚举直到联通找到最大边

    再清空所有关系,从最顶端的边向下枚举找到最小边

    这样这个最大边/最小边的值为一个答案,在所有这些值中找一个最小值

    然后把下限变为这个最小值+1

    重复操作

     1 #include<iostream>
     2 #include<cstdio>
     3 #include<algorithm>
     4 #include<cmath>
     5 #include<cstdlib>
     6 #include<cstring>
     7 #include<queue>
     8 #include<map>
     9 #include<vector>
    10 #define ll long long
    11 #define inf 2147483611
    12 #define MAXN 510
    13 using namespace std;
    14 inline int read()
    15 {
    16     int x=0,f=1;char ch=getchar();
    17     while(!isdigit(ch)) {if(ch=='-') f=-1;ch=getchar();}
    18     while(isdigit(ch)) {x=x*10+ch-'0';ch=getchar();}
    19     return x*f;
    20 }
    21 int f[MAXN],mx,mn,n,m,s,t,ansmx,ansmn;
    22 struct data 
    23 {
    24     int u,v,val;
    25     bool operator < (const data &a) const
    26     {
    27         return val<a.val;
    28     }
    29 }e[MAXN*10];
    30 int find(int x) {return x==f[x]?x:f[x]=find(f[x]);}
    31 int gcd(int a,int b) {return !b?a:gcd(b,a%b);}
    32 void mem() {for(int i=1;i<=n;i++) f[i]=i;}
    33 int main()
    34 {
    35     n=read(),m=read();
    36     for(int i=1;i<=m;i++)
    37         e[i].u=read(),e[i].v=read(),e[i].val=read();
    38     sort(e+1,e+m+1);
    39     s=read(),t=read();
    40     int a,b,st=1;ansmx=inf,ansmn=1;
    41     int i;
    42     while(st<=m)
    43     {
    44         mem();mn=inf,mx=-1;
    45         //cout<<i<<endl;
    46         for(i=st;i<=m;i++)
    47         {
    48         //cout<<i<<" "<<e[i].val<<endl;
    49             a=find(e[i].u),b=find(e[i].v);
    50             if(a!=b) f[a]=b;
    51             if(find(s)==find(t)) {mx=e[i].val;break;}
    52         }
    53         //cout<<mx<<" "<<mn<<" "<<i<<endl;
    54         if(mx==-1&&ansmx==inf) {printf("IMPOSSIBLE");return 0;}
    55         if(mx==-1) break;
    56         mem();
    57         for(;i>=1;i--)
    58         {
    59             a=find(e[i].u),b=find(e[i].v);
    60             if(a!=b) f[a]=b;
    61             if(find(s)==find(t)) {mn=e[i].val;break;}
    62         }
    63         //cout<<mx<<" "<<mn<<" "<<i<<endl;
    64         st=i+1;
    65         if(mn==inf&&ansmx==inf) {printf("IMPOSSIBLE");return 0;}
    66         if(mn==inf) break;
    67         int g=gcd(mx,mn);mx/=g,mn/=g;
    68         if((ll)ansmx*mn>(ll)ansmn*mx) ansmx=mx,ansmn=mn;
    69         //cout<<ansmx<<"  "<<ansmn<<endl;
    70         //system("pause");
    71     }
    72     if(ansmn!=1) printf("%d/%d",ansmx,ansmn);
    73     else printf("%d",ansmx);
    74 }
    View Code
  • 相关阅读:
    GIT笔记
    C++新式类型转换
    C++ 静态链表基本算法实现
    C++ 顺序栈基本算法实现
    C++ 链栈 基本算法实现
    C++ 循环队列基本算法实现
    C++ 链队列基本算法实现
    C++优先级队列表基本算法实现
    C++单链表基本算法实现
    C++ 循环链表基本算法
  • 原文地址:https://www.cnblogs.com/yyc-jack-0920/p/7886124.html
Copyright © 2020-2023  润新知