您的位置:首页 > 其它

bzoj 1050 [HAOI2006]旅行comf [最小生成树] [动点spfa] [LCT]

2016-08-30 17:05 387 查看
1050: [HAOI2006]旅行comf

Time Limit: 10 Sec Memory Limit: 162 MB

Submit: 2740 Solved: 1486

Description

  给你一个无向图,N(N<=500)个顶点, M(M<=5000)条边,每条边有一个权值Vi(Vi<30000)。给你两个顶点S和T

,求一条路径,使得路径上最大边和最小边的比值最小。如果S和T之间没有路径,输出”IMPOSSIBLE”,否则输出

这个比值,如果需要,表示成一个既约分数。 备注: 两个顶点之间可能有多条路径。

Input

  第一行包含两个正整数,N和M。下来的M行每行包含三个正整数:x,y和v。表示景点x到景点y之间有一条双向

公路,车辆必须以速度v在该公路上行驶。最后一行包含两个正整数s,t,表示想知道从景点s到景点t最大最小速

度比最小的路径。s和t不可能相同。

1

#include<iostream>
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<cmath>
#include<vector>
#include<queue>
#include<stack>
#include<map>
#include<set>
#include<string>
#include<iomanip>
#include<ctime>
#include<climits>
#include<cctype>
#include<algorithm>
#ifdef WIN32
#define AUTO "%I64d"
#else
#define AUTO "%lld"
#endif
using namespace std;
#define smax(x,tmp) x=max((x),(tmp))
#define smin(x,tmp) x=min((x),(tmp))
#define maxx(x1,x2,x3) max(max(x1,x2),x3)
#define minn(x1,x2,x3) min(min(x1,x2),x3)
typedef long long LL;
const int INF=0x3f3f3f3f;
const int maxn = 505;
const int maxm = 5005;
LL gcd(LL a,LL b)
{
if(!b) return a;
return gcd(b,a%b);
}
struct Fraction
{
LL numer,deno; // numerator/denominator
void reduce()
{
LL GCD = gcd(numer,deno);
numer/=GCD; deno/=GCD;
}
Fraction (const LL a,const LL b) { numer=a,deno=b; reduce();  }
bool operator < (const Fraction t) const
{
LL GCD=gcd(deno,t.deno);
LL a1=numer*t.deno/GCD;
LL a2=t.numer*deno/GCD;
return a1 < a2;
}
bool operator == (Fraction t)
{
reduce(); t.reduce();
return numer==t.numer && deno==t.deno;
}
};
struct Edge
{
int to,next;
int val;
}edge[maxm<<1];
int head[maxn];
int maxedge;
inline void addedge(int u,int v,int c)
{
edge[++maxedge] = (Edge) { v,head[u],c };
head[u] = maxedge;
edge[++maxedge] = (Edge) { u,head[v],c };
head[v] = maxedge;
}
struct Road
{
int u,v;
int c;
bool operator < (const Road t) const { return c > t.c; }
}road[maxm];
int n,m,S,T;
inline void init()
{
scanf("%d%d",&n,&m);
memset(head,-1,sizeof(head));
maxedge=-1;
for(int i=1;i<=m;i++)
scanf("%d%d%d",&road[i].u,&road[i].v,&road[i].c);
sort(road+1,road+m+1); //decending order
scanf("%d%d",&S,&T);
}
queue <int> que;
bool inque[maxn];
int dis[maxn];
void spfa()
{
while(!que.empty())
{
int u=que.front();que.pop();inque[u]=false;
for(int i=head[u];~i;i=edge[i].next)
{
int v=edge[i].to;
if(dis[v]>max(dis[u],edge[i].val))
{
dis[v]=max(dis[u],edge[i].val);
if(inque[v]) continue;
inque[v]=true;
que.push(v);
}
}
}
}
Fraction work()
{
Fraction ans=Fraction(INF,1);
memset(dis,0x3f,sizeof(dis));
memset(inque,0,sizeof(inque));
dis[S]=0;
for(int i=1;i<=m;i++)
{
addedge(road[i].u,road[i].v,road[i].c);
que.push(road[i].u); que.push(road[i].v);
spfa();
smin(ans,dis[T]<INF?Fraction(dis[T],road[i].c):Fraction(INF,1));
}
return ans;
}
void print(Fraction t)
{
printf("%d",t.numer);
if(t.deno^1ll) printf("/%d",t.deno);
putchar('\n');
}
int main()
{
#ifndef ONLINE_JUDGE
freopen("comf.in","r",stdin);
freopen("comf.out","w",stdout);
#endif
init();
Fraction ans=work();
if(ans==Fraction(INF,1)) puts("IMPOSSIBLE");
else print(ans);
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息