Z小鎮是一個景色宜人的地方,吸引來自各地的觀光客來此旅游觀光。
Z小鎮附近共有
N(1<N≤500)個景點(編號為1,2,3,…,N),這些景點被M(0<M≤5000)條道路連接著,所有道路都是雙向的,兩個景點之間可能有多條道路。也許是為了保護該地的旅游資源,Z小鎮有個奇怪的規定,就是對于一條給定的公路Ri,任何在該公路上行駛的車輛速度必須為Vi。頻繁的改變速度使得游客們很不舒服,因此大家從一個景點前往另一個景點的時候,都希望選擇行使過程中最大速度和最小速度的比盡可能小的路線,也就是所謂最舒適的路線。
第一行包含兩個正整數,N和M。
接下來的M行每行包含三個正整數:x,y和v(1≤x,y≤N,0 最后一行包含兩個正整數s,t,表示想知道從景點s到景點t最大最小速度比最小的路徑。s和t不可能相同。
如果景點s到景點t沒有路徑,輸出“IMPOSSIBLE”。否則輸出一個數,表示最小的速度比。如果需要,輸出一個既約分數。
樣例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
樣例1
IMPOSSIBLE
樣例2
5/4
樣例3
2
N(1<N≤500)
M(0<M≤5000)
Vi在int范圍內


/*貌似是最優比率生成樹,但不會怎么做,問了問同學,是用并查集做的,很神奇。把邊按邊長從小到大排序,枚舉i作為生成樹的最長邊,然后從i到1添邊,直到s和t相連,每次對最長邊與最短邊的比值取小即為答案。至于正確性是顯然的,因為它盡量使生成樹由邊長相近的邊組成,然后取小。 */ #include<cstdio> #include<iostream> #include<algorithm> #define M 510 #define INF 100000000 using namespace std; int fa[M],n,m,s,t; struct node {int x,y,z; };node e[M*10]; bool cmp(const node&a,const node&b) {return a.z<b.z; } int find(int x) {if(fa[x]==x)return x;return fa[x]=find(fa[x]); } int gcd(int a,int b) {if(!b)return a;return gcd(b,a%b); } void print(int x,int y) {if(x%y==0)printf("%d",x/y);else{int t=gcd(x,y);printf("%d/%d",x/t,y/t);} } int main() {scanf("%d%d",&n,&m);for(int i=1;i<=m;i++)scanf("%d%d%d",&e[i].x,&e[i].y,&e[i].z);scanf("%d%d",&s,&t);sort(e+1,e+m+1,cmp);bool flag=false;double ans=INF;int ax,ay;for(int i=1;i<=m;i++){for(int j=1;j<=n;j++)fa[j]=j;for(int j=i;j;j--){int a=find(e[j].x),b=find(e[j].y);if(a!=b)fa[a]=b;if(find(s)==find(t)){if(double(e[i].z)/double(e[j].z)<ans){ans=double(e[i].z)/double(e[j].z);ax=e[i].z;ay=e[j].z;}flag=true;break;}}}if(flag)print(ax,ay);else printf("IMPOSSIBLE");return 0; }
?