codevs 1001 舒适的线路 kruskal/gcd
舒适的线路
Time Limit: 1 Sec Memory Limit: 256 MB
题目连接
http://www.codevs.cn/problem/1001/Description
Z小镇是一个景色宜人的地方,吸引来自各地的观光客来此旅游观光。
Z小镇附近共有
N(1<N≤500)个景点(编号为 1,2,3,…,N),这些景点被M(0<M≤5000)条道路连接着,所有道路都是双向的,两个景点之间可能有多条道路。也许是为了保护该地的旅 游资源,Z小镇有个奇怪的规定,就是对于一条给定的公路Ri,任何在该公路上行驶的车辆速度必须为Vi。频繁的改变速度使得游客们很不舒服,因此大家从一 个景点前往另一个景点的时候,都希望选择行使过程中最大速度和最小速度的比尽可能小的路线,也就是所谓最舒适的路线。
Z小镇附近共有
N(1<N≤500)个景点(编号为 1,2,3,…,N),这些景点被M(0<M≤5000)条道路连接着,所有道路都是双向的,两个景点之间可能有多条道路。也许是为了保护该地的旅 游资源,Z小镇有个奇怪的规定,就是对于一条给定的公路Ri,任何在该公路上行驶的车辆速度必须为Vi。频繁的改变速度使得游客们很不舒服,因此大家从一 个景点前往另一个景点的时候,都希望选择行使过程中最大速度和最小速度的比尽可能小的路线,也就是所谓最舒适的路线。
Input
第一行包含两个正整数,N和M。
接下来的M行每行包含三个正整数:x,y和v(1≤x,y≤N,0 最后一行包含两个正整数s,t,表示想知道从景点s到景点t最大最小速度比最小的路径。s和t不可能相同。
接下来的M行每行包含三个正整数:x,y和v(1≤x,y≤N,0 最后一行包含两个正整数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
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
IMPOSSIBLE
样例2
5/4
样例3
2
HINT
N(1<N≤500)
M(0<M≤5000)
Vi在int范围内
题意
题解:
用kruskal来找就行枚举使用的边数量,枚举最小边,然后搞一搞就好……
最后使用gcd来搞定分数,然后这道题就解决了~
代码:
//qscqesze #include <cstdio> #include <cmath> #include <cstring> #include <ctime> #include <iostream> #include <algorithm> #include <set> #include <vector> #include <sstream> #include <queue> #include <typeinfo> #include <fstream> #include <map> typedef long long ll; using namespace std; //freopen("D.in","r",stdin); //freopen("D.out","w",stdout); #define sspeed ios_base::sync_with_stdio(0);cin.tie(0) #define maxn 200001 #define mod 10007 #define eps 1e-9 //const int inf=0x7fffffff; //无限大 const int inf=0x3f3f3f3f; /* inline ll read() { int x=0,f=1;char ch=getchar(); while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();} while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();} return x*f; } int buf[10]; inline void write(int i) { int p = 0;if(i == 0) p++; else while(i) {buf[p++] = i % 10;i /= 10;} for(int j = p-1; j >=0; j--) putchar('0' + buf[j]); printf("\n"); } */ //************************************************************************************** inline ll read() { int x=0,f=1;char ch=getchar(); while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();} while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();} return x*f; } struct node { int x,y,z; }; node a[maxn]; int fa[maxn]; bool cmp(node a,node b) { return a.z<b.z; } int fi(int x) { if(x!=fa[x]) return fi(fa[x]); return x; } void un(int x,int y) { x=fi(x); y=fi(y); if(x!=y) fa[y]=x; } int gcd(int x,int y) { return y==0?x:gcd(y,x%y); } int main() { int n,m,s,t; n=read(),m=read(),s=read(),t=read(); for(int i=0;i<m;i++) cin>>a[i].x>>a[i].y>>a[i].z; sort(a,a+n,cmp); double mi=inf; int ans[2]; ans[0]=-1; ans[1]=-1; for(int i=0;i<m;i++) { for(int j=0;j<n+1;j++) fa[j]=j; for(int j=i;j<m;j++) { un(a[j].x,a[j].y); if(fi(s)==fi(t)) { if(mi*a[i].z>=a[j].z*1.0) { mi=a[j].z*1.0/a[i].z; ans[0]=a[i].z; ans[1]=a[j].z; } } } } if(ans[0]==-1) cout<<"IMPOSSIBLE"<<endl; else { cout<<ans[1]<<" "<<ans[0]<<endl; int x=gcd(ans[1],ans[0]); ans[1]/=x; ans[0]/=x; if(ans[1]%ans[0]==0) cout<<ans[1]/ans[0]<<endl; else cout<<ans[1]<<"/"<<ans[0]<<endl; } }