您的位置:首页 > 其它

[bzoj1050] [HAOI2006]旅行comf

2017-03-01 17:38 288 查看
给定一张图,和S,T,你要求一条从S到T的路径使得路上的最大边和最小边的比值最小

n<=500,m<=5000

题解:枚举最小的边,然后从小到大加边并用并查集维护连通性.

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#define INF 2000000000
using namespace std;
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;
}

int ans1=INF,ans2=1;
int n,m,S,T;
struct edge{
int from,to,w;
}e[5005];
int s[505];

bool cmp(edge x,edge y){return x.w<y.w;}
int getfa(int x){return s[x]==x?x:s[x]=getfa(s[x]);}
int gcd(int a,int b){return b==0?a:gcd(b,a%b);}

int main()
{
n=read();m=read();
for(int i=1;i<=m;i++)
{
e[i].from=read();e[i].to=read();e[i].w=read();
}S=read();T=read();
sort(e+1,e+m+1,cmp);
int j;
for(int i=1;i<=m;i++)
{
for(j=1;j<=n;j++) s[j]=j;
for(j=i;j<=m;j++)
{
int x=getfa(e[j].from),y=getfa(e[j].to);
if(x!=y) s[x]=y;if(getfa(S)==getfa(T))break;
}
if(j<=m) if((double)e[j].w/e[i].w<(double)ans1/ans2)ans1=e[j].w,ans2=e[i].w;
}
if(ans1==INF)return 0*puts("IMPOSSIBLE");
int x=gcd(ans1,ans2);ans1/=x;ans2/=x;
if(ans2==1)printf("%d\n",ans1);
else printf("%d/%d\n",ans1,ans2);
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: