• BZOJ 1050 旅行


    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不可能相同。

    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

    HINT

    【数据范围】

    1<  N < = 500

    1 < = x, y < = N,0 < v < 30000,x ≠ y

    0 < M < =5000

    Source

    自己YY了一个做法,感觉复杂度有点不太对,但跑起来还是飞快的。

    枚举最大的边权,然后根据当前求出的最优答案找出最小边权,在这个范围内的边中做一遍最大生成树。先用并查集判断两点是否联通:不联通直接再见;否则再找出两点路径的最大值来更新答案。应该很好写,我都能想出来。

     1 #include<cstring>
     2 #include<iostream>
     3 #include<algorithm>
     4 #include<cstdio>
     5 #include<cstdlib>
     6 using namespace std;
     7 
     8 #define inf (1<<30)
     9 #define maxn 510
    10 #define maxm 5010
    11 
    12 int n,m,up,down,side[maxn],toit[maxn*2],next[maxn*2];
    13 int s,t,tot,cnt,father[maxn],bac[maxm],arr[maxn],len[maxn*2];
    14 double ans = (double)inf; bool in[maxn];
    15 struct EDGE
    16 {
    17     int x,y,v;
    18     friend inline bool operator <(const EDGE &a,const EDGE &b) { return a.v > b.v; }
    19 }edge[maxm],temp[maxm];
    20 
    21 inline void init() { for (int i = 1;i <= n;++i) father[i] = i; }
    22 
    23 inline int find(int a) { if (father[a]!=a) father[a] = find(father[a]); return father[a]; }
    24 
    25 inline int gcd(int a,int b) { return b?gcd(b,a%b):a; }
    26 
    27 inline void add(int a,int b,int c)
    28 {
    29     next[++cnt] = side[a]; side[a] = cnt;
    30     toit[cnt] = b; len[cnt] = c;
    31 }
    32 
    33 inline void ins(int a,int b,int c) { add(a,b,c); add(b,a,c); }
    34 
    35 inline int bfs()
    36 {
    37     int team[maxn],*head,*tail;
    38     head = tail = team; memset(in,false,n+2);
    39     *(++tail) = s; in[s] = true; arr[s] = inf;
    40     while (head != tail)
    41     {
    42         int now = *(++head);
    43         if (now == t) return arr[t];
    44         for (int i = side[now];i;i = next[i])
    45             if (!in[toit[i]]) *(++tail) = toit[i],arr[toit[i]] = min(arr[now],len[i]),in[toit[i]] = true;
    46     }
    47 }
    48 
    49 inline void work(int key)
    50 {
    51     int lim = key/ans,all = 0,k = 0;
    52     for (int i = 1;i <= m;++i) if (edge[i].v>lim&&edge[i].v <= key) temp[++all] = edge[i];
    53     init(); memset(side,0,4*(n+2)); cnt = 0;
    54     sort(temp+1,temp+all+1);
    55     for (int i = 1;i <= all;++i)
    56     {
    57         int r1 = find(temp[i].x),r2 = find(temp[i].y);
    58         if (r1 != r2)
    59             father[r1] = r2,ins(temp[i].x,temp[i].y,temp[i].v),++k;
    60         if (k == n-1) break;
    61     }
    62     if (find(s) != find(t)) return;
    63     lim = bfs();
    64     if ((1.0*key)/(1.0*lim) < ans) ans = (1.0*key)/(1.0*lim),up = key,down = lim;
    65 }
    66 
    67 int main()
    68 {
    69     freopen("1050.in","r",stdin);
    70     freopen("1050.out","w",stdout);
    71     scanf("%d %d",&n,&m);
    72     init();
    73     for (int i = 1;i <= m;++i)
    74     {
    75         int a,b,c; scanf("%d %d %d",&a,&b,&c);
    76         edge[i] = (EDGE){a,b,c};
    77         int r1 = find(a),r2 = find(b);
    78         if (r1 != r2) father[r1] = r2;
    79         bac[++tot] = c;
    80     }
    81     scanf("%d %d",&s,&t);
    82     if (find(s) != find(t)) printf("IMPOSSIBLE
    "),exit(0);
    83     sort(bac+1,bac+tot+1); tot = unique(bac+1,bac+tot+1)-bac-1;
    84     for (int i = tot;i;--i) work(bac[i]);
    85     int d = gcd(up,down);
    86     up /= d; down /= d;
    87     if (down != 1) printf("%d/%d",up,down);
    88     else printf("%d",up);
    89     fclose(stdin); fclose(stdout);
    90     return 0;
    91 }
    View Code
  • 相关阅读:
    Java面试题(01)
    HTML学习笔记16——尺寸的表示_px、%、em三种
    HTML学习笔记14——HTML 有语义的标签3_字符实体
    HTML13_有语义的标签2_a标签(超链接,锚点,伪类)
    HTML学习笔记12——HTML 有语义的标签1(h,p标签,img标签,列表,表格_制作课程表)
    HTML学习笔记11——CSS 初始化
    HTML学习笔记9——CSS精确控制背景图片位置——background-position
    HTML学习笔记8——CSS设置背景图片
    CSS控制文字的一些基本属性的使用
    HTML学习笔记5——盒模型(这里有棵圣诞树。)
  • 原文地址:https://www.cnblogs.com/mmlz/p/4276765.html
Copyright © 2020-2023  润新知