hdu 1598(并查集(krustra)+暴力枚举)

 开始看见这道题,题目要问任意两点之间的差值最小的路,我以为是FLOYd算法,举了几个简单的例子发现可行,但是交上去之后却wa了。

后开看别人的题解才知道不是。

做法是,

1.将所有边按照速度大小排序。

2.从排好序的边中拿出一个边作为假设结果集的路径当中的速度最小的边,然后枚举比这条边大的边,加入到生成树中,检查要问的起点和终点是否联通,若联通则说明第一次拿出的边和最后拿出的边的差值就可能是答案。

3.从小到大枚举第一个拿出的边,并作2。枚举完后就得出了答案。

#include <iostream>
#include <memory.h>
#include <stdio.h>
#include <algorithm>
#define INF 10000000
using namespace std;
int N,M;
int parent[205];
struct Edge
{
    int S,E,W;
    bool friend operator<(Edge e1,Edge e2)
    {
        return e1.W<e2.W;
    }
};
Edge A[1005];

int findP(int x)
{
    if(parent[x]==x)
        return x;
    else
    {
        return parent[x]=findP(parent[x]);
    }
}
void Union(int x,int y)
{
    int xp=findP(x),yp=findP(y);
    parent[yp]=xp;
}
void krustra(int s,int e)
{
    int ans=INF;
    for(int i=0;i<M;i++)
    {
        for(int j=0;j<=N;j++)
            parent[j]=j;
        for(int j=i;j<M;j++)
        {
            Union(A[j].S,A[j].E);
            if(findP(s)==findP(e))
            {
                 ans=min(ans,A[j].W-A[i].W);
                 break;
            }
        }
    }
    if(ans==INF)
        cout<<-1<<endl;
    else
        cout<<ans<<endl;
}
int main()
{
    int a,b,speed,Q;
    while(~scanf("%d%d",&N,&M))
    {
        for(int i=0;i<M;i++)
        {
            scanf("%d%d%d",&A[i].S,&A[i].E,&A[i].W);
        }
        sort(A,A+M);
        scanf("%d",&Q);
        while(Q--)
        {
            scanf("%d%d",&a,&b);
            krustra(a,b);
        }
    }
    return 0;
}

  

posted on 2015-08-17 16:08  insaneman  阅读(163)  评论(0)    收藏  举报

导航