题意分析
一开始想用最短路的方法维护,然后更新信息。失败了。
想了半天,发现跟lrj书上面的一道题很像,看边才5000,暴力可做。
对边排序后枚举sta,直到发现起点和重点在一个联通块里面,统计答案即可。
代码总览
#include<bits/stdc++.h>
using namespace std;
const int nmax = 5005;
typedef struct{
int f, t, w;
}Edge;
Edge e[nmax];
int fa[505];
int n,m,s,t;
int mmin = 0x3f3f3f3f, mmax = -1,ansofmmin, ansofmmax;
bool cmp(Edge a, Edge b){return a.w > b.w;}
int findset(int x){
int rt = x ,temp;
while(rt != fa[rt]) rt = fa[rt];
while(x != rt){
temp = fa[x];
fa[x] = rt;
x = temp;
}
return rt;
}
bool unionset(int x, int y){
x = findset(x);
y = findset(y);
if(x == y) return false;
else{
fa[x ] = y;
return true;
}
}
bool getans(){
sort(e,e+m,cmp);
bool isok = false;
for(int j = 0;j<m-1;++j){
for(int i = 1;i<=n;++i) fa[i] = i;
mmin = 0x3f3f3f3f, mmax = -1;
for(int i = j ;i<m;++i){
if(unionset(e[i].f,e[i].t)){
mmin = min(mmin,e[i].w);
mmax = max(mmax,e[i].w);
}
if(findset(s) == findset(t)){
isok = true;
if(ansofmmax == 0 || 1.0 * ansofmmax / (1.0*ansofmmin) > mmax * 1.0 / (mmin * 1.0) ){
ansofmmax = mmax;
ansofmmin = mmin;
}
break;
}
}
}
return isok;
}
int main(){
scanf("%d %d",&n,&m);
for(int i = 0;i<m;++i) scanf("%d %d %d",&e[i].f,&e[i].t,&e[i].w);
scanf("%d %d",&s,&t);
bool isok = getans();
if(!isok) printf("IMPOSSIBLE\n");
else {
int gcd = __gcd(ansofmmax,ansofmmin);
if(ansofmmin / gcd == 1) printf("%d\n",ansofmmax/gcd);
else printf("%d/%d\n",ansofmmax/gcd,ansofmmin/gcd);
}
return 0;
}