一开始以为是01分数规划,后来发现不知道怎么写。
发现只需要关心S,T的连通性和最长边最小边,而且边又那么少,可以枚举。
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cmath>
using namespace std;
const int N=5005;
int n,m,mn,mx,fa[505],s,t;double ans;
struct Edge{int x,y,val;}e[N<<1];
bool cmp(Edge x,Edge y) {return x.val<y.val;}
int find(int x){return fa[x]==x?x:fa[x]=find(fa[x]);}
int klskr(int now) {
int ans,cnt=0;
for(int i=1;i<=n;i++) fa[i]=i;
for(int i=now;i<=m;i++) {
int u=find(e[i].x),v=find(e[i].y);
if(u!=v) {fa[u]=fa[v];ans=e[i].val;cnt++;if(find(s)==find(t)) return ans;}
}
return -1;
}
int main() {
ans=999999999;
scanf("%d%d",&n,&m);
mx=-1,mn=-1;
for(int i=1;i<=m;i++) scanf("%d%d%d",&e[i].x,&e[i].y,&e[i].val);
sort(e+1,e+1+m,cmp);scanf("%d%d",&s,&t);
for(int i=1;i<=m;i++) {
int now=klskr(i);
if(now!=-1)
if(1.0*now/(1.0*e[i].val)<ans) ans=(1.0*now)/(1.0*e[i].val),mn=e[i].val,mx=now;
}
if(mx==mn&&mx==-1) puts("IMPOSSIBLE");
else if(mx%mn) printf("%d/%d",mx/__gcd(mx,mn),mn/__gcd(mx,mn));
else printf("%d",mx/mn);
}