zoukankan      html  css  js  c++  java
  • 【BZOJ】【1050】【HAOI2006】旅行comf

    枚举/暴力/Kruskal


      orz……我sb了……其实是sb题<_<

      有一道题问的是最小极差生成树……(不记得是什么名字了,就是求最大边权与最小边权差最小的生成树)做法是枚举最小边,然后kruskal找最大边

      这题同理,因为$mleq 5000$,所以$m^2$的算法即可……

     1 /**************************************************************
     2     Problem: 1050
     3     User: Tunix
     4     Language: C++
     5     Result: Accepted
     6     Time:312 ms
     7     Memory:1336 kb
     8 ****************************************************************/
     9  
    10 //BZOJ 1050
    11 #include<vector>
    12 #include<cstdio>
    13 #include<cstring>
    14 #include<cstdlib>
    15 #include<iostream>
    16 #include<algorithm>
    17 #define rep(i,n) for(int i=0;i<n;++i)
    18 #define F(i,j,n) for(int i=j;i<=n;++i)
    19 #define D(i,j,n) for(int i=j;i>=n;--i)
    20 #define pb push_back
    21 using namespace std;
    22 inline int getint(){
    23     int v=0,sign=1; char ch=getchar();
    24     while(ch<'0'||ch>'9'){ if (ch=='-') sign=-1; ch=getchar();}
    25     while(ch>='0'&&ch<='9'){ v=v*10+ch-'0'; ch=getchar();}
    26     return v*sign;
    27 }
    28 const int N=510,M=5010,INF=~0u>>2;
    29 typedef long long LL;
    30 /******************tamplate*********************/
    31 int n,m,s,t,fa[N];
    32 struct edge{int x,y,v;}e[M];
    33 inline bool cmp(edge a,edge b){return a.v<b.v;}
    34 inline int Find(int x){return fa[x]==x?x:Find(fa[x]);}
    35 inline int gcd(int a,int b){return b?gcd(b,a%b):a;}
    36 int main(){
    37 #ifndef ONLINE_JUDGE
    38     freopen("1050.in","r",stdin);
    39     freopen("1050.out","w",stdout);
    40 #endif
    41     n=getint(); m=getint();
    42     F(i,1,m){
    43         e[i].x=getint(); e[i].y=getint(); e[i].v=getint();
    44     }
    45     s=getint(); t=getint();
    46     sort(e+1,e+m+1,cmp);
    47     int j,min=-1,max=-1;
    48     F(i,1,m){
    49         if (e[i].v==e[i-1].v)continue;
    50         for(j=1;j<=n;j++) fa[j]=j;
    51         for(j=i;j<=m;j++){
    52             int f1=Find(e[j].x),f2=Find(e[j].y);
    53             if (f1!=f2) fa[f1]=f2;
    54             if (Find(s)==Find(t)) break;
    55         }
    56         if (j<=m && (min==-1||double(max)/min>double(e[j].v)/e[i].v)){
    57             min=e[i].v;
    58             max=e[j].v;
    59         }
    60     }
    61     if (min==-1) puts("IMPOSSIBLE");
    62     else{
    63         if (max%min==0) printf("%d
    ",max/min);
    64         else printf("%d/%d
    ",max/gcd(max,min),min/gcd(max,min));
    65     }
    66     return 0;
    67 }
    View Code

    1050: [HAOI2006]旅行comf

    Time Limit: 10 Sec  Memory Limit: 162 MB
    Submit: 1693  Solved: 849
    [Submit][Status][Discuss]

    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

    [Submit][Status][Discuss]
  • 相关阅读:
    SQL盲注工具BBQSQL
    嗅探X-Windows服务按键工具xspy
    多协议底层攻击工具Yesinia
    LLMNR欺骗工具Responder
    Arduino可穿戴教程保存源文件与打开已经存在的源文件
    GRDB使用SQLite的WAL模式
    CString之GetBuffer与ReleaseBuffer
    VC++ 模块与资源分离
    KV6.60 SP1
    Html之head部分详解
  • 原文地址:https://www.cnblogs.com/Tunix/p/4433339.html
Copyright © 2011-2022 走看看