zoukankan      html  css  js  c++  java
  • BZOJ1050 [HAOI2006]旅行comf

    Description

      给你一个无向图,N(N<=500)个顶点, M(M<=5000)条边,每条边有一个权值Vi(Vi<30000)。给你两个顶点S和T
    ,求一条路径,使得路径上最大边和最小边的比值最小。如果S和T之间没有路径,输出”IMPOSSIBLE”,否则输出
    这个比值,如果需要,表示成一个既约分数。 备注: 两个顶点之间可能有多条路径。

    Input

      第一行包含两个正整数,N和M。下来的M行每行包含三个正整数:x,y和v。表示景点x到景点y之间有一条双向
    公路,车辆必须以速度v在该公路上行驶。最后一行包含两个正整数s,t,表示想知道从景点s到景点t最大最小速
    度比最小的路径。s和t不可能相同。
    1<N<=500,1<=x,y<=N,0<v<30000,0<M<=5000

    Output

      如果景点s到景点t没有路径,输出“IMPOSSIBLE”。否则输出一个数,表示最小的速度比。如果需要,输出一
    个既约分数。

    Sample Input

    【样例输入1】
    4 2
    1 2 1
    3 4 2
    1 4
    【样例输入2】
    3 3
    1 2 10
    1 2 5
    2 3 8
    1 3
    【样例输入3】
    3 2
    1 2 2
    2 3 4
    1 3

    Sample Output

    【样例输出1】
    IMPOSSIBLE
    【样例输出2】
    5/4
    【样例输出3】
    2

     

     

    正解:并查集

    解题报告:

      考场上开始写了一个SPFA,然而是萎的,然后又yy了一下,感觉枚举答案中的两条边似乎可行,但是做不到O(1)判断可行性。

      之后想出来一种更优秀的算法:我只需要枚举最大权值的边,然后比它权值小的边都可以用,知道S和T连通就更新一下答案,从大往小枚举。

      具体见代码:

     1 //It is made by jump~
     2 #include <iostream>
     3 #include <cstdlib>
     4 #include <cstring>
     5 #include <cstdio>
     6 #include <cmath>
     7 #include <algorithm>
     8 #include <ctime>
     9 #include <vector>
    10 #include <queue>
    11 #include <map>
    12 #include <set>
    13 #ifdef WIN32   
    14 #define OT "%I64d"
    15 #else
    16 #define OT "%lld"
    17 #endif
    18 using namespace std;
    19 typedef long long LL;
    20 const int MAXN = 520;
    21 const int MAXM = 10011;
    22 int n,m,s,t,ecnt;
    23 int father[MAXN];
    24 int ans1,ans2;
    25 double ans;
    26 struct edge{
    27     int u,v,z;
    28 }e[MAXM];
    29 
    30 inline int getint()
    31 {
    32        int w=0,q=0;
    33        char c=getchar();
    34        while((c<'0' || c>'9') && c!='-') c=getchar();
    35        if (c=='-')  q=1, c=getchar();
    36        while (c>='0' && c<='9') w=w*10+c-'0', c=getchar();
    37        return q ? -w : w;
    38 }
    39 
    40 inline int find(int x){
    41     if(father[x]!=x) father[x]=find(father[x]); 
    42     return father[x];
    43 }
    44 
    45 inline int gcd(int x,int y){
    46     if(y==0) return x;
    47     return gcd(y,x%y);
    48 }
    49 
    50 inline bool cmp(edge q,edge qq){ return q.z<qq.z; }
    51 
    52 inline void work(){
    53     n=getint(); m=getint();
    54     for(int i=1;i<=m;i++){ e[i].u=getint(); e[i].v=getint(); e[i].z=getint();    }
    55     s=getint(); t=getint();
    56     sort(e+1,e+m+1,cmp);
    57     int r1,r2; ans=(1<<30);
    58     double now;
    59     for(int i=1;i<=m;i++){
    60     for(int j=1;j<=n;j++) father[j]=j;
    61     for(int j=i;j>=1;j--) {
    62         r1=find(e[j].u); r2=find(e[j].v);
    63         if(r1!=r2) father[r2]=r1;
    64         r1=find(s); r2=find(t);
    65         if(r1==r2) {
    66         now=(double)e[i].z/(double)e[j].z;
    67         if(now<ans) { ans=now; ans1=e[i].z; ans2=e[j].z; }
    68         break;
    69         }
    70     }    
    71     }
    72     if(ans==(1<<30)) { printf("IMPOSSIBLE"); return ; }
    73 
    74     int gong=gcd(ans1,ans2);
    75     if(ans1==ans2) printf("1");
    76     else  if(gong==ans2) printf("%d",ans1/ans2);
    77     else  printf("%d/%d",ans1/gong,ans2/gong);
    78 }
    79 
    80 int main()
    81 {
    82   work();
    83   return 0;
    84 }
  • 相关阅读:
    spring mvc拦截器和<mvc:annotation-driven />的详解
    SpringMVC的工作流程-005
    子线程循环10次,接着主线程循环100次,接着又回到子线程循环10次,接着再回到主线程循环100次,如此循环50次-004
    简单java死锁设计002
    uwsgi手动安装时报错ValueError: invalid literal for int() with base 10: '32_1'
    flask jinja的宏
    Flask Web 开发 错误页面自定义
    Flask权限管理
    python uwsgi报错epoll_ctl(): Bad file descriptor
    linux怎么上真正的国际互联网
  • 原文地址:https://www.cnblogs.com/ljh2000-jump/p/5803080.html
Copyright © 2011-2022 走看看