bzoj 1050 旅行comf
题目大意:
一个无向图,N(N<=500)个顶点, M(M<=5000)条边,每条边有一个权值Vi(Vi<30000)
两个顶点S和T,求一条路径,使得路径上最大边和最小边的比值最小
如果S和T之间没有路径,输出”IMPOSSIBLE” 否则输出这个比值(最简)
思路:
我们可以枚举所有边的下限
先按边权排序
然后从这条边开始向上枚举直到联通找到最大边
再清空所有关系,从最顶端的边向下枚举找到最小边
这样这个最大边/最小边的值为一个答案,在所有这些值中找一个最小值
然后把下限变为这个最小值+1
重复操作
1 #include<iostream> 2 #include<cstdio> 3 #include<algorithm> 4 #include<cmath> 5 #include<cstdlib> 6 #include<cstring> 7 #include<queue> 8 #include<map> 9 #include<vector> 10 #define ll long long 11 #define inf 2147483611 12 #define MAXN 510 13 using namespace std; 14 inline int read() 15 { 16 int x=0,f=1;char ch=getchar(); 17 while(!isdigit(ch)) {if(ch=='-') f=-1;ch=getchar();} 18 while(isdigit(ch)) {x=x*10+ch-'0';ch=getchar();} 19 return x*f; 20 } 21 int f[MAXN],mx,mn,n,m,s,t,ansmx,ansmn; 22 struct data 23 { 24 int u,v,val; 25 bool operator < (const data &a) const 26 { 27 return val<a.val; 28 } 29 }e[MAXN*10]; 30 int find(int x) {return x==f[x]?x:f[x]=find(f[x]);} 31 int gcd(int a,int b) {return !b?a:gcd(b,a%b);} 32 void mem() {for(int i=1;i<=n;i++) f[i]=i;} 33 int main() 34 { 35 n=read(),m=read(); 36 for(int i=1;i<=m;i++) 37 e[i].u=read(),e[i].v=read(),e[i].val=read(); 38 sort(e+1,e+m+1); 39 s=read(),t=read(); 40 int a,b,st=1;ansmx=inf,ansmn=1; 41 int i; 42 while(st<=m) 43 { 44 mem();mn=inf,mx=-1; 45 //cout<<i<<endl; 46 for(i=st;i<=m;i++) 47 { 48 //cout<<i<<" "<<e[i].val<<endl; 49 a=find(e[i].u),b=find(e[i].v); 50 if(a!=b) f[a]=b; 51 if(find(s)==find(t)) {mx=e[i].val;break;} 52 } 53 //cout<<mx<<" "<<mn<<" "<<i<<endl; 54 if(mx==-1&&ansmx==inf) {printf("IMPOSSIBLE");return 0;} 55 if(mx==-1) break; 56 mem(); 57 for(;i>=1;i--) 58 { 59 a=find(e[i].u),b=find(e[i].v); 60 if(a!=b) f[a]=b; 61 if(find(s)==find(t)) {mn=e[i].val;break;} 62 } 63 //cout<<mx<<" "<<mn<<" "<<i<<endl; 64 st=i+1; 65 if(mn==inf&&ansmx==inf) {printf("IMPOSSIBLE");return 0;} 66 if(mn==inf) break; 67 int g=gcd(mx,mn);mx/=g,mn/=g; 68 if((ll)ansmx*mn>(ll)ansmn*mx) ansmx=mx,ansmn=mn; 69 //cout<<ansmx<<" "<<ansmn<<endl; 70 //system("pause"); 71 } 72 if(ansmn!=1) printf("%d/%d",ansmx,ansmn); 73 else printf("%d",ansmx); 74 }