BUAA 418 Little Busters!(并查集)

题目链接:http://acm.buaa.edu.cn/problem/418/

题意:给出一个带权无向图以及起点s和终点t。求一条从s到t的路径,使得路径上权值最大最小的比值最小?

思路:将边按照权值降序排序,枚举上限。




struct node

{

    int u,v,dis;

};



const int INF=2000000000;

int C;

int n,m,e,s,t;

node E[10005];



int cmp(node a,node b)

{

    return a.dis<b.dis;

}



int Gcd(int x,int y)

{

    return !y?x:Gcd(y,x%y);

}



int Set[505];



int find(int x)

{

    if(Set[x]!=x) Set[x]=find(Set[x]);

    return Set[x];

}



int OK(int x,int &y)

{

    int i,p,q;

    for(i=1;i<=n;i++) Set[i]=i;

    for(i=x;i>=0;i--)

    {

        p=find(E[i].u);

        q=find(E[i].v);

        if(p==q) continue;

        Set[p]=q;

        if(find(s)==find(t))

        {

            y=i;

            return 1;

        }

    }

    return 0;

}



int main()

{

    for(scanf("%d",&C);C--;)

    {

        scanf("%d%d",&n,&m);

        int i,u,v,dis;

        e=0;

        for(i=1;i<=m;i++)

        {

            scanf("%d%d%d",&u,&v,&dis);

            E[e].u=u;

            E[e].v=v;

            E[e++].dis=dis;

        }

        scanf("%d%d",&s,&t);

        sort(E,E+e,cmp);

        int flag=0,Max,Min,x;

        for(i=e-1;i>=0;i--)

        {

            if(OK(i,x))

            {

                if(!flag)

                {

                    flag=1,Max=E[i].dis,Min=E[x].dis;

                }

                else

                {

                    if(E[i].dis*Min<E[x].dis*Max)

                    {

                        Max=E[i].dis;

                        Min=E[x].dis;

                    }

                }

                x=Gcd(Max,Min);

                Max/=x;

                Min/=x;

            }

            else break;

        }

        if(flag)

        {

            if(Min==1) printf("%d\n",Max);

            else printf("%d/%d\n",Max,Min);

        }

        else

        {

            puts("R U Kiddin'?");

        }

    }

    return 0;

}

  

 

你可能感兴趣的:(并查集)