HDU2544 最短路模板题 Dijkstra

题目链接

【题意】
图中有N个点,M条边,求1到N的最短时间。保证有解。
N<=100,M<=10000
【分析】
很裸的最短路,但是也好长时间没有打Dijkstra了,而且之前也没有打过+优先队列的,在这里试试,然后WA了好几发。。。。
最后发现优先队列更新的时候d[x]打成了p[i].v
仔细想想,dijkstra本身的思想就是维护两个集合,第一组为已求出最短路径的顶点集合(用S表示),第二组为其余未确定最短路径的顶点集合(用U表示),按最短路径长度的递增次序依次把U中的顶点加入S中。

【Code】

#include
#include
#include
#include
#include
#include
#include
#include
using namespace std;

typedef long long LL;
#define INF 0x3f3f3f3f
const int MAX_N = 10000 + 10;
const int MAX_M = 40000 + 10;

int d[MAX_N], head[MAX_N];
bool v[MAX_N];
int n, m, cnt;
struct edge{
    int from, to, v, next;
} p[MAX_M];
struct node{
    int num, val;
    bool operator <(const node &c)const {
        return val > c.val;
    }
};

void add(int u, int v, int w)
{
    p[cnt].from = u;
    p[cnt].to = v;
    p[cnt].v = w;
    p[cnt].next = head[u];
    head[u] = cnt++;
}
void dijkstra(int s)
{
    for (int i=1;i<=n;i++) d[i] = INF;
    memset(v,0,sizeof(v));
    priority_queue pq;
    while (!pq.empty()) pq.pop();
    d[s] = 0;
    node t;
    pq.push((node){s,0});
    while (!pq.empty()){
        t = pq.top();
        pq.pop();
        int u = t.num;
        if (v[u]) continue;
        v[u] = true;
        for (int i=head[u];i!=-1;i=p[i].next){
            int x = p[i].to;
            if (d[x] > d[u] + p[i].v){
                d[x] = d[u] + p[i].v;
                pq.push((node){x,d[x]});
            }
        }
    }
}
int main()
{
    int x, y, z;
    while (~scanf("%d%d",&n,&m)&&n){
        memset(head,-1,sizeof(head));
        cnt = 0;
        for (int i=0;iscanf("%d%d%d",&x,&y,&z);
            add(x,y,z);
            add(y,x,z);
        }
        dijkstra(1);
        printf("%d\n",d[n]);
    }
}

你可能感兴趣的:(图论)