BZOJ1050

来源:互联网 发布:轻音乐软件 编辑:程序博客网 时间:2024/05/29 13:59

传送门:BZOJ1050

CODEVS上做过这道题,当时写了一个二分+贪心……
今天回来看发现就是傻逼贪心。
枚举最大值,贪心最小值,并查集维护即可。
代码上的小细节见下。

#include <cstdio>#include <cstdlib>#include <cmath>#include <cstring>#include <iostream>#include <algorithm>using namespace std;struct Edge{    int u,v;    int w;    Edge(){        u=0,v=0;        w=0;    }    Edge(int u_,int v_,int w_){        u=u_,v=v_;        w=w_;    }    bool operator <(const Edge& a)const{        return w<a.w;    }};int fa[505];Edge edge[5005];int n,m;int p,q;double ans=1e9;int s,t;int find(int a){    if(fa[a]!=a)        fa[a]=find(fa[a]);    return fa[a];}void Union(int a,int b){    fa[find(a)]=find(b);}bool Near(int a,int b){    return find(a)==find(b);}void Clear(){    for(int i=1;i<=n;i++)        fa[i]=i;}int gcd(int a,int b){    if(b==0)        return a;    return gcd(b,a%b);}void Solve(){    sort(edge+1,edge+1+m);    for(int i=1;i<=m;i++){        Clear();        int p_=edge[i].w,q_=0x3f3f3f3f;        for(int j=i;j>=1;j--)            if(!Near(edge[j].u,edge[j].v)){                Union(edge[j].u,edge[j].v);                q_=edge[j].w;                if(Near(s,t))                    break;            }        if(!Near(s,t))            continue;        if((double)p_/(double)q_<ans){            p=p_,q=q_;            ans=(double)p/double(q);        }    }    if(p==0&&q==0)        printf("IMPOSSIBLE");    else        if(p%q==0)            printf("%d",p/q);        else            printf("%d/%d",p/gcd(p,q),q/gcd(p,q));}void Readdata(){    freopen("loli.in","r",stdin);    scanf("%d%d",&n,&m);    for(int i=1;i<=m;i++)        scanf("%d%d%d",&edge[i].u,&edge[i].v,&edge[i].w);    scanf("%d%d",&s,&t);}void Close(){    fclose(stdin);    fclose(stdout);}int main(){    Readdata();    Solve();    Close();    return 0;}
0 0
原创粉丝点击