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
     
     
     
    题目中要求的最小比值涉及两个值,因此枚举其中一个,再贪心求另一个。比如先枚举最小的,然后将比它大的边按从小到大的顺序加入并查集,直到s和t连通,最后加入的边就是最好的最大边。
     1 program rrr(input,output);
     2 const
     3   inf=123456789;
     4   eps=1e-8;
     5 var
     6   u,v,w:array[0..5050]of longint;
     7   father:array[0..505]of longint;
     8   n,m,s,t,i,j,c,d,p,q:longint;
     9   min:double;
    10 procedure sort(q,h:longint);
    11 var
    12   i,j,x,t:longint;
    13 begin
    14    i:=q;j:=h;x:=w[(i+j)>>1];
    15    repeat
    16      while w[i]<x do inc(i);
    17      while x<w[j] do dec(j);
    18      if i<=j then
    19         begin
    20            t:=u[i];u[i]:=u[j];u[j]:=t;
    21            t:=v[i];v[i]:=v[j];v[j]:=t;
    22            t:=w[i];w[i]:=w[j];w[j]:=t;
    23            inc(i);dec(j);
    24         end;
    25    until i>j;
    26    if j>q then sort(q,j);
    27    if i<h then sort(i,h);
    28 end;
    29 function find(k:longint):longint;
    30 begin
    31    if father[k]=k then exit(k);
    32    father[k]:=find(father[k]);
    33    exit(father[k]);
    34 end;
    35 function gcd(a,b:longint):longint;
    36 var
    37   r:longint;
    38 begin
    39    r:=a mod b;
    40    while r<>0 do begin a:=b;b:=r;r:=a mod b; end;
    41    exit(b);
    42 end;
    43 begin
    44    assign(input,'r.in');assign(output,'r.out');reset(input);rewrite(output);
    45    readln(n,m);
    46    for i:=1 to m do readln(u[i],v[i],w[i]);
    47    readln(s,t);
    48    sort(1,m);
    49    min:=inf;
    50    for i:=1 to m do
    51       begin
    52          for j:=1 to n do father[j]:=j;
    53          for j:=i to m do
    54             begin
    55                c:=find(u[j]);d:=find(v[j]);
    56                if c<>d then father[c]:=d;
    57                c:=find(s);d:=find(t);
    58                if c=d then break;
    59             end;
    60          if c=d then if w[j]/w[i]<min then begin min:=w[j]/w[i];p:=w[i];q:=w[j]; end;
    61       end;
    62    if abs(min-inf)<eps then write('IMPOSSIBLE')
    63    else begin c:=gcd(p,q);p:=p div c;q:=q div c;if p=1 then write(q) else write(q,'/',p); end;
    64    close(input);close(output);
    65 end.
  • 相关阅读:
    简单数列极限证明
    既然已经半退役了,就写点新东西吧
    快速幂(整数+实数)
    D. Constant Palindrome Sum 差分+思维
    排序网络
    ClickHouse数据同步
    C++ 复习
    使用mac查看iphone uuid方法
    15. 蓝绿发布导致需求不能验证
    通过反射获取对象的属性名、属性值
  • 原文地址:https://www.cnblogs.com/Currier/p/6493296.html
Copyright © 2011-2022 走看看