bzoj1050【HAOI2006】旅行comf

1050: [HAOI2006]旅行comf

Time Limit: 10 Sec  Memory Limit: 162 MB
Submit: 2205  Solved: 1174
[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




思路非常像最小生成树

先将边依照权值从小到大排序。

枚举最小边,将其它边按顺序依次加进去,直到s和t属于一个集合,用并查集维护。




#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cmath>
#include<cstring>
#include<algorithm>
#define F(i,j,n) for(int i=j;i<=n;i++)
#define D(i,j,n) for(int i=j;i>=n;i--)
#define ll long long
#define maxn 505
#define maxm 5005
using namespace std;
struct data{int x,y,z;}a[maxm];
int n,m,s,t,mn,mx,p[maxn];
inline int 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;
}
inline bool cmp(data a1,data a2)
{
	return a1.z<a2.z;
}
inline int find(int x)
{
	return p[x]==x?x:p[x]=find(p[x]);
}
inline void merge(int x,int y)
{
	int fx=find(x),fy=find(y);
	if (fx!=fy) p[fx]=fy;
}
inline int gcd(int x,int y)
{
	return y?

gcd(y,x%y):x; } int main() { n=read();m=read(); F(i,1,m){a[i].x=read();a[i].y=read();a[i].z=read();} sort(a+1,a+m+1,cmp); s=read();t=read(); F(i,1,m) { F(j,1,n) p[j]=j; merge(a[i].x,a[i].y); int tmp=i; while (tmp<m&&find(s)!=find(t)) { tmp++; merge(a[tmp].x,a[tmp].y); } if (find(s)!=find(t)) continue; if (tmp>m) tmp=i; if (!mx||(a[tmp].z*1.0/a[i].z<mx*1.0/mn)) { mx=a[tmp].z; mn=a[i].z; } } if (!mx) printf("IMPOSSIBLE "); else if (mx%mn==0) printf("%d ",mx/mn); else { int tmp=gcd(mx,mn); printf("%d/%d ",mx/tmp,mn/tmp); } }



原文地址:https://www.cnblogs.com/yjbjingcha/p/7209463.html