codevs 1001 舒適的路線
阿新 • • 發佈:2017-05-11
name sam font 最大 輸出 車輛 資源 fault clas
題目描述 Description
輸出描述 Output Description
首先將路線按照速度從小到大排序
枚舉每個最大速度 然後再找小於最大速度的路線
利用並查集 將邊聯通起來 構成個生成樹 看s,t是否可以聯通 找到直接比較更新max_ans與min_ans即可。
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”。否則輸出一個數,表示最小的速度比。如果需要,輸出一個既約分數。
樣例輸入 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
樣例1
IMPOSSIBLE
樣例2
5/4
樣例3
2
N(1<N≤500)
M(0<M≤5000)
Vi在int範圍內
分析: 簡單的並查集,加上一點小貪心。類似最小生成樹。#include<iostream> #include<algorithm> using namespace std; int n,m; const int inf=9999999; struct node{ int s; int f; int w; }a[5010]; int fx[501]; int gcd(int a,int b) { returnb==0?a:gcd(b,a%b); } void init() { for(int i=1;i<=n;++i)fx[i]=i; } bool cmp(const node &a,const node &b) { return a.w<b.w; } int find(int n) { if(fx[n]==n)return n; else return fx[n]=find(fx[n]); } bool mer(int s,int f) { int a=find(s),b=find(f); if(a!=b) { fx[b]=a; return 1; } else return 0; } int main() { int max_ans=inf,min_ans=1; int s,t; cin>>n>>m; for(int i=1;i<=m;++i)cin>>a[i].s>>a[i].f>>a[i].w; cin>>s>>t; sort(a+1,a+m+1,cmp); for(int i=1;i<=m;++i) { init(); for(int j=i;j>=1;--j) { mer(a[j].s,a[j].f); if(find(s)==find(t)) { if((double)max_ans/min_ans>(double)a[i].w/a[j].w) { max_ans=a[i].w; min_ans=a[j].w; break; } } } } if(max_ans==inf&&min_ans==1) { cout<<"IMPOSSIBLE"; return 0; } //cout<<max_ans<<" "<<max_min; if(max_ans%min_ans==0) { cout<<max_ans/min_ans; } else { int t; t=gcd(max_ans,min_ans); max_ans/=t; min_ans/=t; cout<<max_ans<<"/"<<min_ans; } return 0; }
codevs 1001 舒適的路線