[bzoj1050 HAOI2006] 旅行comf (kruskal)
傳送門(mén)
Description
給你一個(gè)無(wú)向圖,N(N<=500)個(gè)頂點(diǎn), M(M<=5000)條邊,每條邊有一個(gè)權(quán)值Vi(Vi<30000)。給你兩個(gè)頂點(diǎn)S和T,求
一條路徑,使得路徑上最大邊和最小邊的比值最小。如果S和T之間沒(méi)有路徑,輸出”IMPOSSIBLE”,否則輸出這個(gè)
比值,如果需要,表示成一個(gè)既約分?jǐn)?shù)。 備注: 兩個(gè)頂點(diǎn)之間可能有多條路徑。
Input
第一行包含兩個(gè)正整數(shù),N和M。下來(lái)的M行每行包含三個(gè)正整數(shù):x,y和v。表示景點(diǎn)x到景點(diǎn)y之間有一條雙向公路
,車輛必須以速度v在該公路上行駛。最后一行包含兩個(gè)正整數(shù)s,t,表示想知道從景點(diǎn)s到景點(diǎn)t最大最小速度比
最小的路徑。s和t不可能相同。
1<N<=500,1<=x,y<=N,0<v<30000,0<M<=5000
Output
如果景點(diǎn)s到景點(diǎn)t沒(méi)有路徑,輸出“IMPOSSIBLE”。否則輸出一個(gè)數(shù),表示最小的速度比。
如果需要,輸出一個(gè)既約分?jǐn)?shù)。
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
沒(méi)什么明顯的提示qwq
題目是要找兩條符合條件邊求比值,發(fā)現(xiàn)m是5000的可以先枚舉其中一條邊再\(O(m)\)地找另一條邊就能行
這個(gè)題是要在s和t聯(lián)通的情況下,找到最小比值,那么如果確定一條最小邊,只需要找到最大邊最小的的方案使st連通其中的最大邊就是當(dāng)前情況的最優(yōu)邊
于是就想到了kruskal的方法,直接套上去發(fā)現(xiàn)所有要求就都滿足了ヽ( ̄▽ ̄)ノ
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; }轉(zhuǎn)載于:https://www.cnblogs.com/Menteur-Hxy/p/9371979.html
總結(jié)
以上是生活随笔為你收集整理的[bzoj1050 HAOI2006] 旅行comf (kruskal)的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 简单举例JAVA回调函数的实现
- 下一篇: python ppt表格样式展示