codevs 1001 舒适的路线

codevs 1001 舒适的路线

1.看到题目,要找某种最优条件,又是二维图,用搜索,然后这个应该是DFS,并且判断是否能到达也不是问题。但新的一个问题是,2个点之间可能存在多条边,这个我思前想后也不知道该如何进行存储这个数据。

2.突然感觉这好像是个非常神难的题,看题解吧。

3.看了题解才发现,原来思维还是挺简单的,下面转载一份题解:

4.以前被这个题吓到了。。。以为是个神题。。。木有想到数据范围支持 暴力+并查集。。。

把边 按照权值(也就是题目中 能在边上行驶的最大速度v) 升序排列

然后从左到右扫一遍所有的边

比如现在扫到了一条边x(这时并查集要赋值成原始值)

就把x作为要选的 权值最小边,然后往这条边的右边扫,并且用并查集不断维护连通性

这里相当于就是只能选比 边x 权值大的边

直到找到一条边y,且y满足 加上这条边y 使起点和终点 能联通

那么边y就是 使得起点和终点相通的边集中 最大边 

相当于枚举分母,并求出该分母对应的最小分子 然后对所有求得的分数取最小值的过程。。。

这样扫一遍,取min就好了。。。

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#define N 5009
using namespace std;

int n,m,la,fa[N],maxx,minn,ans2,ans1,beg,end;

struct node
{
    int fr,to,len;
}a[N];
void addedge(int x,int y,int z)
{
    a[++la].fr=x,a[la].to=y,a[la].len=z;
}
int cmp(node a,node b)
{
    return a.len<b.len;
}
int find(int x)
{
    if (x==fa[x]) return x;
    fa[x]=find(fa[x]);
    return fa[x];
}
int gcd(int x,int y)
{
    if (y==0)return x;else return gcd(y,x%y);
}
int main()
{
    int i,j,k,x,y,z;
    cin>>n>>m;
    for(i=1;i<=m;i++) 
        {
            scanf("%d%d%d",&x,&y,&z);
            addedge(x,y,z);
        }
    cin>>beg>>end;
    sort(a+1,a+m+1,cmp);
    for (i=1;i<=m;i++)
    {
            for (j=1;j<=n;j++) fa[j]=j;
            maxx=0;
            minn=2*1e9;
            for (j=i;j<=m;j++) // 只考虑更长的边 
            {
                if (find( a[j].fr )!=find( a[j].to ))
                {
                    fa[ find( a[j].fr ) ]=find( a[j].to );
                    maxx=max(maxx,a[j].len);
                    minn=min(minn,a[j].len);
                    if (find(beg)==find(end)) break;
                }
            }
            if (find(beg)==find(end)) //联通的 
                if(!ans1 && !ans2 || maxx*ans2 < ans1*minn) //大小比例更小 
                    ans1=maxx,ans2=minn;    
    }
    // ans1为 最大速度,ans2为最小速度 
    if (!ans1&&!ans2) cout<<"IMPOSSIBLE"<<endl;
        else if (ans1%ans2==0) cout<<ans1/ans2<<endl;
            else cout<<ans1/gcd( ans1,ans2 )<<"/"<<ans2/gcd(ans1,ans2);

}```

转载至:http://codevs.cn/wiki/solution/?problem_id=1001

5.现在想来,看起来很难的题目也许思路是很简单的,不要轻易地被表面迷惑了。可能有其他的解决途径,而且还要多发散思维,不畏挫折。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值