zoukankan      html  css  js  c++  java
  • [bzoj1050 HAOI2006] 旅行comf (kruskal)

    传送门

    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

    Solution

    没什么明显的提示qwq
    题目是要找两条符合条件边求比值,发现m是5000的可以先枚举其中一条边再(O(m))地找另一条边就能行
    这个题是要在s和t联通的情况下,找到最小比值,那么如果确定一条最小边,只需要找到最大边最小的的方案使st连通其中的最大边就是当前情况的最优边
    于是就想到了kruskal的方法,直接套上去发现所有要求就都满足了ヽ( ̄▽ ̄)ノ

    Code

    //By Menteur_Hxy
    #include<cstdio>
    #include<cstring>
    #include<cstdlib>
    #include<iostream>
    #include<algorithm>
    #define F(i,a,b) for(register int i=(a);i<=(b);i++)
    using namespace std;
    
    int read() {
    	int x=0,f=1; char c=getchar();
    	while(!isdigit(c)) {if(c=='-')f=-f; c=getchar();}
    	while(isdigit(c)) x=(x<<1)+(x<<3)+c-48,c=getchar();
    	return x*f;
    }
    
    const int N=510,M=5010;
    int n,m,s,t,amx,ami;
    int fa[N];
    double ans=2333333333.0;
    struct eds{int fr,to,w;}ed[M];
    
    int gcd(int a,int b) {return !b?a:gcd(b,a%b);}
    int getf(int x) {return fa[x]==x?x:fa[x]=getf(fa[x]);}
    bool cmp(eds x,eds y) {return x.w<y.w;}
    
    int main() {
    	n=read(),m=read();
    	F(i,1,m) {
    		int a=read(),b=read(),c=read();
    		ed[i]=(eds){a,b,c};
    	}
    	s=read(),t=read();
    	sort(ed+1,ed+1+m,cmp);
    //	cout<<endl;
    	F(i,1,m) {
    		F(j,1,n) fa[j]=j;
    		int mi=ed[i].w;
    		F(j,i,m) {
    			int fu=getf(ed[j].fr),fv=getf(ed[j].to);
    //			cout<<fu<<" "<<fv<<endl;
    			if(fu!=fv) fa[fu]=fv;
    //			cout<<getf(s)<<" "<<getf(t)<<endl;
    //			cout<<endl;
    			if(getf(s)==getf(t)) {
    				int mx=ed[j].w;
    				double res=(double)mx/mi;
    //				cout<<res<<endl;
    				if(res<ans) amx=mx,ami=mi,ans=res;
    				break;
    			}
    		}
    	}
    	if(ans==2333333333.0) puts("IMPOSSIBLE");
    	else if(amx%ami==0) printf("%d",amx/ami);
    	else {
    		int d=gcd(amx,ami);
    		printf("%d/%d",amx/d,ami/d);
    	}
    	return 0;
    }
    
    版权声明:本文为博主原创文章,未经博主允许不得转载。 博主:https://www.cnblogs.com/Menteur-Hxy/
  • 相关阅读:
    Boost练习程序(multi_index_container)
    mathematica练习程序(图像取反)
    【转】媒体播放器三大底层架构
    CentOS安装中文支持
    Retrofit2文件上传下载及其进度显示
    Andorid面试问题整理
    5分钟实现Android中更换头像功能
    Android中突发情况Activity数据的保存和恢复
    5分钟让你学会用最高效的工具解析所有Json
    android http 和https请求
  • 原文地址:https://www.cnblogs.com/Menteur-Hxy/p/9371979.html
Copyright © 2011-2022 走看看