每日一题 [HAOI2006]旅行 题解
简单题,我们发现边数和点数都很小
允许我们可以用平方做法来做,然后我们直接枚举最小的边权,依次往上最小做生成树,然后把所有得出的答案取个最优就可以了,在这里我们可以把并查集的复杂度看成是O(1)的,因为边数只有500。
具体细节需要我们判断分数的大小和一些无解的情况,看一下代码就ok了
代码:
#include<bits/stdc++.h>
#define LL long long
using namespace std;
const int N=505,M=5e3+5;
struct Graph{int u,v,w;}gra[M];
int n,m,s,t,fa[N],fz=-1,fm=-1;
int find(int u){return fa[u]==u?u:fa[u]=find(fa[u]);}
bool Cmp(int x,int y,int x2,int y2){return (fz==-1&&fm==-1)||x*y2<x2*y;}
bool cmp(Graph a,Graph b){return a.w<b.w;}
int main(){
scanf("%d%d",&n,&m);
for(int i=1;i<=m;i++)scanf("%d%d%d",&gra[i].u,&gra[i].v,&gra[i].w);
scanf("%d%d",&s,&t);
sort(gra+1,gra+m+1,cmp);
for(int i=1,res,maw;i<=m;i++){
bool fl=false;
for(int j=1;j<=n;j++)fa[j]=j;
for(int j=i,u,v;j<=m;j++){
u=gra[j].u;v=gra[j].v;
if(find(u)!=find(v)){
fa[fa[u]]=fa[v];
if(find(s)==find(t)){maw=gra[j].w;fl=true;break;}
}
}
if(!fl){
if(i==1){puts("IMPOSSIBLE");return 0;}
break;
}
if(Cmp(maw,gra[i].w,fz,fm))fz=maw,fm=gra[i].w;
}
int g=__gcd(fz,fm);fz/=g;fm/=g;
if(fz%fm==0)printf("%d\n",fz/fm);else printf("%d/%d\n",fz,fm);
return 0;
}
网易游戏公司福利 566人发布