POJ 1135 Domino Effect(Dijkstra)

POJ 1135 Domino Effect(Dijkstra)

http://poj.org/problem?id=1135

题意: 

        有一些多米若骨牌,其中有一些关键牌.(这些关键牌可以看成无向图的顶点,关键牌之间的普通牌看成是无向图的边). 然后构成了一个具有n个点,m条边的无向图,每条边有行走时间.现在问你最后倒下的骨牌是不是关键牌,且时间是多少?

分析:

        最后倒下的骨牌只有两种情况:关键牌或者非关键牌.

        由于骨牌都是从1号骨牌开始倒下的,所以我们只需要算出从1点到其他所有点的距离即可算出,其他关键骨牌的倒塌时间的最大值MAX_1.(想想是不是)

        然后我们要算出m条边中(包括两端点)的最晚倒塌的骨牌的时间是多少? 对于a点与b点构成的边,假设a点在d[a]倒塌,b点在d[b]倒塌,且边(a,b)的权值(时间)为 edges[i].dist,所以该边中骨牌的最晚倒塌时间为: (d[a]+d[b]+edges[i].dist)/2 (仔细想想是不是)  记录最大的这种值MAX_2且记录该值对应的两个端点编号.

        如果MAX_1 < MAX_2,说明最后倒塌的是普通骨牌.

        如果MAX_1>=MAX_2,说明最后倒塌的是关键骨牌.

AC代码:

#include<cstdio>
#include<cstring>
#include<algorithm>
#include<vector>
#include<queue>
using namespace std;
const int maxn= 500+10;
int n,m;
struct Edge
{
    int from,to;
    double dist;
    Edge(){}
    Edge(int from,int to,double d):from(from),to(to),dist(d){}
}e[maxn*maxn];
struct HeapNode
{
    double dist;
    int u;
    HeapNode(double dist,int u):dist(dist),u(u){}
    bool operator < (const HeapNode &rhs) const
    {
        return dist > rhs.dist;
    }
};
struct Dijkstra
{
    int n,m;
    vector<Edge> edges;
    vector<int> G[maxn];
    bool done[maxn];
    double d[maxn];

    void init(int n)
    {
        this->n=n;
        for(int i=0;i<n;i++) G[i].clear();
        edges.clear();
    }

    void AddEdge(int from,int to,double dist)
    {
        edges.push_back(Edge(from,to,dist) );
        m=edges.size();
        G[from].push_back(m-1);
    }

    void dijkstra()
    {
        priority_queue<HeapNode> Q;
        for(int i=0;i<n;i++) d[i]= 1e15;
        d[0]=0.0;
        Q.push(HeapNode(d[0],0));
        memset(done,0,sizeof(done));

        while(!Q.empty())
        {
            HeapNode x=Q.top(); Q.pop();
            int u =x.u;
            if(done[u]) continue;
            done[u]=true;

            for(int i=0;i<G[u].size();i++)
            {
                Edge &e=edges[G[u][i]];
                if(d[e.to] > d[u]+e.dist)
                {
                    d[e.to] = d[u]+e.dist;
                    Q.push(HeapNode(d[e.to],e.to));
                }
            }
        }
    }
}DJ;
int main()
{
    int kase=1;
    while(scanf("%d%d",&n,&m)==2&&n)
    {
        DJ.init(n);
        for(int i=0;i<m;i++)
        {
            scanf("%d%d%lf",&e[i].from,&e[i].to,&e[i].dist);
            e[i].from--;
            e[i].to--;
            DJ.AddEdge(e[i].from,e[i].to,e[i].dist);
            DJ.AddEdge(e[i].to,e[i].from,e[i].dist);
        }
        DJ.dijkstra();

        double max_v1=-1;
        int max_v1_point;
        for(int i=0;i<n;i++)if(max_v1 < DJ.d[i])
        {
            max_v1 = DJ.d[i];
            max_v1_point = i;
        }

        double max_v2=-1;
        int max_v2_p1,max_v2_p2;
        for(int i=0;i<m;i++)
        {
            int u=e[i].from, v=e[i].to, dist=e[i].dist;
            if(max_v2 < (DJ.d[u]+DJ.d[v]+dist)/2)
            {
                max_v2 = (DJ.d[u]+DJ.d[v]+dist)/2;
                max_v2_p1 = min(u,v);
                max_v2_p2 = max(u,v);
            }
        }

        if(max_v1 < max_v2)
        {
            printf("System #%d\nThe last domino falls after ",kase++);
            printf("%.1lf seconds, between key dominoes %d and %d.\n\n",max_v2,max_v2_p1+1,max_v2_p2+1);
        }
        else
        {
            printf("System #%d\nThe last domino falls after ",kase++);
            printf("%.1lf seconds, at key domino %d.\n\n",max_v1,max_v1_point+1);
        }
    }
    return 0;
}


你可能感兴趣的:(Algorithm,算法,ACM)