zoukankan      html  css  js  c++  java
  • POJ2387(Til the Cows Come Home)

    这题就是裸的最短路,而且边权都为非负,可以直接用dijkstra来求。

    写这题主要是为了练习一下dijkstra的优先级队列实现,提交后运行时间为63MS,比一般的dijkstra快一点(97MS)。

    后来又尝试用SPFA写,结果还是63MS。

    在写dijkstra的优先级队列实现和SPFA的过程中发现,这两个算法非常类似,不过,SPFA用的是一般的队列。

    SPFA
    #include <stdio.h>
    #include <string.h>
    #include <queue>
    using namespace std;
    #define MIN(a,b) ((a)<(b)?(a):(b))
    #define N 1000
    #define INF 100000
    int n,m;
    int d[N][N],dist[N],inq[N];
    struct node
    {
        int u;
        friend bool operator <(node x,node y)
        {
            return dist[x.u]>dist[y.u];
        }
    };
    void spfa(int s)
    {
        int u,v;
        node cur,next;
        queue<node> q;
        memset(inq,0,sizeof(inq));
        for(u=0;u<n;u++)    dist[u]=INF;
        dist[s]=0;
        cur.u=s;
        q.push(cur);
        inq[s]=1;
        while(!q.empty())
        {
            cur=q.front(),q.pop();
            u=cur.u;
            inq[u]=0;
            for(v=0;v<n;v++)
            {
                if(dist[v]>dist[u]+d[u][v])
                {
                    dist[v]=dist[u]+d[u][v];
                    next.u=v;
                    if(inq[v]==0)   q.push(next);
                }
            }
        }
    }
    int main()
    {
        int i,j,a,b,x;
        while(~scanf("%d%d",&m,&n))
        {
            for(i=0;i<n;i++)
            {
                for(j=0;j<i;j++)    d[i][j]=d[j][i]=INF;
            }
            for(i=0;i<m;i++)
            {
                scanf("%d%d%d",&a,&b,&x);
                a--,b--;
                d[a][b]=d[b][a]=MIN(d[a][b],x);
            }
            spfa(0);
            printf("%d\n",dist[n-1]);
        }
        return 0;
    }
    优先级队列实现的dijkstra
    #include <stdio.h>
    #include <string.h>
    #include <queue>
    #define MIN(a,b) ((a)<(b)?(a):(b))
    #define N 1000
    #define INF 100000
    using namespace std;
    int n,m;
    int d[N][N];
    int dist[N],vis[N];
    struct node
    {
        int u,g;
        friend bool operator <(node x,node y)
        {
            return x.g>y.g;
        }
    };
    void dijkstra(int s)
    {
        int u,v,gu,gv;
        node cur,next;
        priority_queue<node> pq;
        memset(vis,0,sizeof(vis));
        for(u=0;u<n;u++)    dist[u]=INF;
        cur.u=s;
        cur.g=0;
        pq.push(cur);
        while(!pq.empty())
        {
            cur=pq.top(),pq.pop();
            u=cur.u;
            gu=cur.g;
            vis[u]++;
            if(vis[u]>1)    continue;
            dist[u]=gu;
            for(v=0;v<n;v++)
            {
                if(vis[v]==0 && dist[v]>=gu+d[u][v])
                {
                    dist[v]=gv=gu+d[u][v];
                    next.u=v;
                    next.g=gv;
                    pq.push(next);
                }
            }
        }
    }
    int main()
    {
        int i,j,a,b,x;
        while(~scanf("%d%d",&m,&n))
        {
            for(i=0;i<n;i++)
            {
                for(j=0;j<i;j++)    d[i][j]=d[j][i]=INF;
            }
            for(i=0;i<m;i++)
            {
                scanf("%d%d%d",&a,&b,&x);
                a--,b--;
                d[a][b]=d[b][a]=MIN(d[a][b],x);
            }
            dijkstra(0);
            printf("%d\n",dist[n-1]);
        }
        return 0;
    }
  • 相关阅读:
    ASP.NET编程的十大技巧
    C#学习心得(转)
    POJ 1177 Picture (线段树)
    POJ 3067 Japan (树状数组)
    POJ 2828 Buy Tickets (线段树)
    POJ 1195 Mobile phones (二维树状数组)
    HDU 4235 Flowers (线段树)
    POJ 2886 Who Gets the Most Candies? (线段树)
    POJ 2418 Cows (树状数组)
    HDU 4339 Query (线段树)
  • 原文地址:https://www.cnblogs.com/algorithms/p/2582757.html
Copyright © 2011-2022 走看看