[HAOI2006]旅行

一开始以为是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);
}
我是咸鱼。转载博客请征得博主同意Orz
原文地址:https://www.cnblogs.com/sdfzhsz/p/9375386.html