动点spfa,并不知道复杂度多少。
#include<cstdio>
#include<iostream>
#include<algorithm>
#include<cstring>
#include<cmath>
#include<vector>
#include<queue>
using namespace std;
const int maxn = 1001050;
int dist[maxn],val[maxn],n,m,x,y,z,s,t,a,b;
double ans=1e7;
vector<int> f[maxn],g[maxn];
queue<int> Q;
bool vis[maxn];
struct edge{
int x,y,z;
}T[maxn];
bool operator < (edge a,edge b)
{
return a.z>b.z;
}
int gcd(int a,int b)
{
if(!b) return a;
else return gcd(b,a%b);
}
inline void spfa()
{
while(!Q.empty())
{
int u=Q.front();Q.pop();vis[u]=false;
for(int i=0;i<f[u].size();i++)
{
int v=f[u][i];
if(dist[v]>max(dist[u],g[u][i])){
dist[v]=max(dist[u],g[u][i]);
if(!vis[v]){
vis[v]=true;Q.push(v);
}
}
}
}
}
int main()
{
scanf("%d%d",&n,&m);
for(int i=1;i<=m;i++)
scanf("%d%d%d",&T[i].x,&T[i].y,&T[i].z);
scanf("%d%d",&s,&t);
sort(T+1,T+1+m);
memset(dist,0x3f,sizeof(dist));
dist[s]=0;
for(int i=1;i<=m;i++)
{
x=T[i].x,y=T[i].y,z=T[i].z;
f[x].push_back(y);g[x].push_back(z);
f[y].push_back(x);g[y].push_back(z);
if(dist[x]<dist[y]) swap(x,y);
if(dist[x]<=max(dist[y],T[i].z))
continue;
dist[x]=max(dist[y],T[i].z);
Q.push(x);vis[x]=true;
spfa();
if((double)dist[t]/T[i].z<ans)
ans=(double)dist[t]/T[i].z,a=dist[t],b=T[i].z;
}
if(ans==1e7)
puts("IMPOSSIBLE");
else if(a%b==0)
printf("%d",a/b);
else
printf("%d/%d",a/gcd(a,b),b/gcd(a,b));
return 0;
}
HOME Back