失踪百景

惯性生存者

导航

kuangbin_ShortPath P (HDU 4725)

很有挑战的一题 直接暴力建图的话毫无疑问O(n^2)会TLE 每层虚拟一个点又会让没有点的层也能连过去

参考kuangbin菊苣的方法每层用了两个虚拟点 n+i*2-1 是入口 n+i*2 是出口 然后建单向边就可以了

VA了一次 因为MAXN应该比数据量大两倍 不小心忽略了 至于MAXM直接开到了1e7

#include <iostream>
#include <string>
#include <cstdio>
#include <cmath>
#include <cstring>
#include <queue>
#include <map>
#include <vector>
#include <set>
#include <algorithm>
#define INF 0x3F3F3F3F
using namespace std;

const int MAXN = 1e6 + 10;
const int MAXM = 2e7 + 10;

typedef pair<int, int> pii;
struct cmp{
    bool operator ()(const pii a, const pii b){
        return a.first > b.first;
    }
};

int size, head[MAXN], point[MAXM], nxt[MAXM], val[MAXM];
int t, n, m, c, dist[MAXN];

void init()
{
    size = 0;
    memset(head, -1, sizeof head);
}

inline void add(int from, int to, int value)
{
    val[size] = value;
    point[size] = to;
    nxt[size] = head[from];
    head[from] = size++;
}

void dij(){
    priority_queue<pii, vector<pii>, cmp> q;
    memset(dist, 0x3f, sizeof dist);
    q.push(make_pair(0, 1));
    dist[1] = 0;
    while(!q.empty()){
        pii u = q.top();
        q.pop();
        if(u.first > dist[u.second]) continue;
        for(int i = head[u.second]; ~i; i = nxt[i]){
            if(dist[point[i]] > dist[u.second] + val[i]){
                dist[point[i]] = dist[u.second] + val[i];
                q.push(make_pair(dist[point[i]], point[i]));
            }
        }
    }
}

int main()
{
    scanf("%d", &t);
    for(int kase = 1; kase <= t; kase++){
        init();
        scanf("%d%d%d", &n, &m, &c);
        for(int i = 1; i <= n; i++){
            int layer;
            scanf("%d", &layer);
            add(n + 2*layer - 1, i, 0);
            add(i, n + 2*layer, 0);
        }
        for(int i = 1; i < n; i++){
            add(n + 2*i, n + 2*(i+1) - 1, c);
            add(n + 2*(i+1), n + 2*i - 1, c);
        }
        int u, v, w;
        for(int i = 1; i <= m; i++){
            scanf("%d%d%d", &u, &v, &w);
            add(u, v, w);
            add(v, u, w);
        }
        
        dij();
        printf("Case #%d: %d\n", kase, dist[n] == INF ? -1 : dist[n]);
    }
    return 0;
}

 

posted on 2016-01-14 20:19  失踪百景  阅读(160)  评论(0编辑  收藏  举报