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

题意:有向图,第一行n是点数,m是边数,每一行有三个数,前两个是有向边的起点与终点,最后一个是权值,求从1到n的最短路径。

思路:这个题让会神给讲的,用的dijkstra,看的网上很多用SPFA的。

关于SPFA:http://www.cnblogs.com/devtang/archive/2011/08/25/spfa.html

http://blog.csdn.net/chenjiang492943457/article/details/5375413
关于差分约束系统:http://www.cnblogs.com/void/archive/2011/08/26/2153928.html

代码:

#include <stdio.h>
#include <string.h>
#include <algorithm>
#include <queue>

using namespace std ;
const int maxn = 30005 ;
const int maxm = 150005 ;
int head[maxn],next[maxm] ;
int map[maxn] ;
bool vis[maxn] ;
const int INF = 1<<23 ;
int cnt , n , m;
struct node
{
    int u ;
    int v ;
    int c ;
    node(){}
    node(int u,int v,int c):u(u),v(v),c(c){}

}edge[maxm] ;

struct node1
{
    int v,c ;
    node1(){}
    node1(int v,int c):v(v),c(c){}
    bool operator <(const node1 &a)const
    {
        return c > a.c ;
    }
} ;
void addnode(int u,int v,int c)
{
    edge[cnt] = node(u,v,c) ;
    next[cnt] = head[u] ;
    head[u] = cnt++ ;
} ;
bool relax(int u,int v,int c)
{
    if(map[v] > map[u] + c)
    {
        map[v] = map[u]+c ;
        return true ;
    }
    return false ;
}

void Init()
{
    memset(head,-1,sizeof(head)) ;
    memset(next,-1,sizeof(next)) ;
    cnt = 0 ;
    for(int i = 0 ; i < m ; i++)
    {
        int x,y,z ;
        scanf("%d %d %d",&x,&y,&z) ;
        addnode(x,y,z) ;
    }
}

void dija(int sh)
{
    memset(vis,0,sizeof(vis)) ;
    for(int i = 1 ; i <= n ; i++)
    map[i] = INF ;
    map[sh] = 0 ;
    priority_queue<node1>Q ;
    Q.push(node1(sh,map[sh])) ;
    for(int i = 0 ; i < n ; i++)
    {
        while(!Q.empty() && vis[Q.top().v]) Q.pop() ;
        if(Q.empty()) break ;
        node1 temp = Q.top() ;
        Q.pop() ;
        vis[temp.v] = true ;
        for(int j = head[temp.v] ; j != -1 ; j = next[j])
        {
            if(relax(temp.v,edge[j].v,edge[j].c) && !vis[edge[j].v])
            Q.push(node1(edge[j].v,map[edge[j].v])) ;
        }
    }
}
int main()
{
    while(~scanf("%d %d",&n,&m))
    {
        Init() ;
        dija(1) ;
        printf("%d\n",map[n]) ;
    }
    return 0 ;
}
View Code

 

posted on 2014-01-18 20:23  枫、  阅读(243)  评论(0编辑  收藏  举报