MZ自测——遥远的村庄(并查集)

来源:互联网 发布:sql默认地址不详设置 编辑:程序博客网 时间:2024/04/26 15:02

3、遥远的村庄

village.c/cpp/pas

1s/64M

 

【问题描述】

XX住在一个遥远的村庄里,这个村庄有N户居民(编号为1,2,3…N),他们之间由M条道路连接起来,道路可以双向通行。第i条道路的距离记为Wi。

一天XX需要第s户居民家去到第t户居民家,他想,既然反正都要去,那为什么不顺便干点有意思的事呢,于是他决定找出一条完美路线。在所有可从s到达t的路线中,如果该路线上最大距离路段和最小距离路段比最小,那么XX则认为这就是完美路线。

 

【输入数据】

输入文件名:village.in

输入第一行为n,m两个数,表示村庄里的有n户居民,他们之间有m条路。

接下来m行每行3个数a,b,c,分别表示从a到b的距离为c。

最后一行是两个数s,t,表示YCX要从s去t。

 

【输出数据】

输出文件名:village.out

一行,一个数表示完美路线上最大距离路段和最小距离路段比,注意,该比值如果不是整数请用最简分数表示。如果不能到达,则直接输出”Impossible”(引号内字符,首字母大写,其余小写)。

 

【输入样例】

样例1

4 2

1 21

3 42

1 4

 

样例2

3 3

1 210

1 25

2 38

1 3

 

样例3

3 2

1 22

2 34

1 3

 

【输出样例】

样例1

Impossible

 

样例2
5/4

样例3

2

【数据范围】

对于100%的数据,<1<N<=500,0<M<=5000,1<Wi<=1000

解析:

           这是本人回归noip的第一篇题解。。。

           有一种类似kruskal的方法,将边从大到小排序。。。枚举最大边和最小边,用并查集来判断起点和终点是否相连。。。

           并更新比值。。。

代码:

#include<cstdio>#include<algorithm>#define inf 0x3f3f3f3fint f[5000];struct node{    int u,v,w;}edge[6000];bool cmp(node a,node b){return a.w>b.w;}int gcd(int a,int b){    if(b==0)return a;    return gcd(b,a%b);}int find(int x){    if(f[x]!=x)return find(f[x]);    return f[x];}void merge(int a,int b){    f[find(a)]=find(b);}void work(){    int n,m,s,t;    scanf("%d%d",&n,&m);    int biggest=-inf,small=inf;    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);    std::sort(edge+1,edge+1+m,cmp);    double flag=inf;    for(int i=1;i<=m;i++)    {        for(int j=1;j<=n;j++)f[j]=j;        for(int k=i;k<=m;k++)        {            if(find(edge[k].u!=find(edge[k].v)))            merge(edge[k].u,edge[k].v);            if(find(s)==find(t))            {                if(edge[i].w*1.0/edge[k].w<flag)                {                    biggest=edge[i].w;                    small=edge[k].w;                    flag=edge[i].w*1.0/edge[k].w;                }                break;            }        }    }    if(flag==inf)printf("Impossible\n");    else    {        int gc=gcd(biggest,small);        if(gc==small)printf("%d",biggest/small);else        printf("%d/%d",biggest/gc,small/gc);    }}int main(){    freopen("village.in","r",stdin);    freopen("village.out","w",stdout);    work();    return 0;}


原创粉丝点击