每日一题 [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;
}
全部评论

相关推荐

ArisRobert:统一解释一下,第4点的意思是,公司按需通知员工,没被通知到的员工是没法去上班的,所以只要没被通知到,就自动离职。就是一种比较抽象的裁员。
点赞 评论 收藏
分享
totoroyyw:千年老妖😂
投递华为等公司10个岗位
点赞 评论 收藏
分享
评论
1
收藏
分享
牛客网
牛客企业服务