UVA10986

题意:给出n,m,s,t,n表示有n个点,m表示有m条边,然后给出m行数据表示m条边,每条边的数据有连接两点的序号以及该边的权值,问说从点s到点t的最短路径是多少。

思路:分析题目的样列可知,这一题是要用邻接矩阵来存储无向图,所以要注意无向图怎么存储在邻阶表。连接表的横列有N项,纵列也是N项。形成的N*N项每项都被称为边结点,每项都有纵横两个坐标,例如点(N,N-1),表示的就是从第N点向第N-1点有无路径。由于有E条边,自然有E条路径,但是由于无向=双向,所以要乘以2


#include <iostream>
#include <cstdio>
#include <cstring>
#include <queue>
#include <vector>
using std::make_pair;
using namespace std;

const int N = 400005;
const int INF = 1 << 30;
typedef pair<int, int> pii;

int n, m, s, t;
int d[N], rec[N];
int first[N], u[N], next[N], v[N], w[N];

struct cmp{
    bool operator() (const int a, const int b){
        return a % 10 > b % 10;  
    }
};

priority_queue<int, vector<pii>, greater<pii> > q;

void init() {
    scanf("%d %d %d %d", &n, &m, &s, &t);
    for (int i = 0; i < n; i++) 
        first[i] = -1;

    m *= 2;
    for (int i = 0; i < m; i++) {
        scanf("%d %d %d", &u[i], &v[i], &w[i]); 
        next[i] = first[u[i]];
        first[u[i]] = i; 

        i++;
        v[i] = u[i - 1] , u[i] = v[i - 1], w[i] = w[i - 1];
        next[i] = first[u[i]];
        first[u[i]] = i; 
    }
}

void dijkstra() {
    bool done[N];
    for (int i = 0; i < n; i++) 
        d[i] = (i == s ? 0 : INF);
    memset(done, 0, sizeof(done));
    q.push(make_pair(d[s], s));
    while (!q.empty()) {
        pii u = q.top();
        q.pop();
        int x = u.second; 
        if (done[x]) 
            continue;
        done[x] = true;
        for (int i = first[x]; i != -1; i = next[i]) {
            if (d[v[i]] > d[x] + w[i]) {
                d[v[i]] = d[x] + w[i]; 
                q.push(make_pair(d[v[i]], v[i])); 
             }
        }
    }
}

int main() {
    int cas, o = 0;
    scanf("%d", &cas);
    while (cas--) {
        init(); 
        dijkstra(); 
        printf("Case #%d: ", ++o); 
        if (d[t] == INF)
            printf("unreachable\n");
        else
            printf("%d\n", d[t]);
    }
    return 0;
}


你可能感兴趣的:(UVA10986)