极品飞车(并查集+枚举)

Posted YJSheep

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了极品飞车(并查集+枚举)相关的知识,希望对你有一定的参考价值。

极品飞车(并查集+枚举)

Hecy被FC星人劫持了!

“长的帅也是一种罪过吗?”,Hecy问劫持他的生物,结果被暴打。唉,原来Hecy被劫持的原因是FC星人看中了他的编程才能(“我真的长的不帅吗?”Hecy不死心地问另一个生物,结果再次被暴打)。

    FC星有许多城市,某些城市之间无法直接到达,但某些城市之间可以通过一种奇怪的高速公路SARS(Super Air Roam Structure 超级空中漫游结构)进行人员或物资的交流运输。在SARS上有且仅有一种“车”可以行驶,那就是传说中的极品飞车Flycar。东东们就是乘坐着Flycar在SARS上运动的。与地球相似地,每条SARS都对行驶在他上面的Flycars有限速要求——不同的是这既不是限最高速,也不是限最低速,而是限固定速,也就是说Flycars必须以所限速度行驶,否则就要被TS(Traffic System)来一次ts(tiger strike虎击)——这可不是好玩的!

同时FC星人对flycar的“舒适度”也有特殊的要求。他们认为乘坐一次flycar过程中,flycar达到的最高速与最低速之间的差越小,本次乘坐越舒适(可以理解,因为SARS的限速要求,flycar都必须瞬间提/降速,痛苦啊)——FC星人对时间却没那么多要求。

因此Hecy的任务就明确了:为FC星上几乎垄断了flycar市场的全星通用汽车公司(CC)设计新一代自动寻路flycar,使得该flycar能自动寻找两城市间最舒适的到达路径。

 

任务

对于给定的公路网以及两个城市s、t,求出从s到t的最舒适路径。

 

输入

输入数据的第一行两个正整数n、m(1<=n〈=200,1〈=m<=1000),n、m分别表示城市数和公路数。

第二行是两个正整数s、t,表示初始城市和目标城市。

接下来的n行每行三个正整数i、j、num(num〈=1000000),表示城市I,j之间有一条道路,该路的限时为num.

 

输出

输出数据的第一行为最舒适值。

第二行依次输出最舒适路径上的城市。

注意:如果有多个数据满足问题的要求,只要输出一个即可。

 

样例输入

2 1

1 2

1 2 1

 

样例输出

0

1 2

 

解题报告

这一题和舒适的路径很像。主要要借助并查集。我们不妨把所有边按从小到大排序。并从小到达枚举边,将其作为最小边,依次按之后的边用并查集将点合并,直到起点与终点相连。这样,最高速度与最低速度的差就是所枚举的最小边与当前边的差。枚举出所有差,取最小值即可。这种解法与最小生成树有异曲同工之妙。

 

 

#include<queue>
#include <algorithm>
#include<cstdio>
#include<cstring>
#include<cmath>
#define Pair pair<int,int>
#define MAXN 1000+10
#define MAXM 600000+1
#define max(a,b) (a>b?a:b)
#define min(a,b) (a<b?a:b)
using namespace std;
int n,m,num,s,t,pre[MAXN],v[MAXM],as;
int fa[MAXM];
struct Edge{
    int dis,next,to,exi,from;
}edge[MAXM];
bool cmp(Edge a,Edge b)
{
    return a.dis<b.dis;
}
int find(int x)
{
    if(fa[x]!=x) fa[x]=find(fa[x]);
    return fa[x];
}
void un(int x,int y)
{
    
    fa[y]=x;
}
void work(int s,int t)
{
    int mind=99999999,flag=0;
    for(int i=1;i<=m;i++)
    {
        for(int j=1;j<=n;j++) fa[j]=j;
        int minn=edge[i].dis,maxn=0;
        for(int j=i;j<=m;j++)
        {
            int a=find(edge[j].from),b=find(edge[j].to);
            if(a!=b)
            {
                un(a,b);
                maxn=edge[j].dis;
                if(find(s)==find(t)) 
                {
                    mind=min(mind,maxn-minn);
                    flag=1;
                    break;
                }
            }
        }
        
    }
    if(mind!=99999999)
    printf("%d\n",mind);
    else printf("-1\n",mind);
}
int main()
{
    freopen("flycar.in","r",stdin);
    freopen("flycar.out","w",stdout);
    scanf("%d%d",&n,&m);
    for(int i=1;i<=m;i++)
    {
        int x,y,z;
        scanf("%d%d%d",&edge[i].from,&edge[i].to,&edge[i].dis);
        
    }
    sort(edge+1,edge+1+m,cmp);
    scanf("%d",&as);
    for(int i=1;i<=as;i++)
    {
        scanf("%d%d",&s,&t);
        work(s,t);
    }
    
    return 0;
}

 

以上是关于极品飞车(并查集+枚举)的主要内容,如果未能解决你的问题,请参考以下文章

poj 2912 Rochambeau(枚举+带权并查集)

POJ 2912 - Rochambeau - [暴力枚举+带权并查集]

poj2912(带权并查集+枚举)

USACO环绕岛屿Surround the Islands 并查集 枚举暴力

[BZOJ1050][HAOI2006]旅行comf 枚举+并查集

BZOJ 1050: [HAOI2006]旅行comf(枚举+并查集)