Magical Girl Haze [ ACM-ICPC 2018 南京赛区网络预赛 ] [ 分层图dij ]

 

There are N cities in the country, and M directional roads from u to v(1≤u,v≤n). Every road has a distance cici
Haze is a Magical Girl that lives in City 1, she can choose no more than K roads and make their distances become 0. Now she wants to go to City N, please help her calculate the minimum distance.

Input
The first line has one integer T(1≤T≤5), then following T cases.
For each test case, the first line has three integersN,M and K.
Then the following M lines each line has three integers, describe a road,Ui,Vi,CiUi,Vi,Ci
There might be multiple edges between u and v.
It is guaranteed that N≤100000,M≤200000,K≤10,
0≤CiCi≤1e9. There is at least one path between City 1 and City N.

Output
For each test case, print the minimum distance.

样例输入
1
5 6 1
1 2 2
1 3 4
2 4 3
3 4 1
3 5 6
4 5 2
样例输出
3

属于比较裸的分层图dijkstra
主要的思想是 : 优先队列优化的 dij 然后 维护 dis 数组的时候 开一个二维的数组第二维表示第几次边为零的情况,在循环里面加一层判断就行

AC code:

#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
#include <queue>

using namespace std;

typedef long long ll;
typedef pair<int,int> pii;

const int maxn = 1e5+50;
const int maxm = 2e5+50;
const int inf = 0x3f3f3f3f;
const int mod = 1e9+7;

struct Node{
    int u,v;
    ll w;
    bool operator<(const Node& a) const {
        if ( u == a.u && v == a.v ) return w > a.w;
        else if ( u == a.u ) return v < a.v;
        else return u < a.u;
    }
}edge[maxm];

struct node{
    int to,nxt;
    ll w;
}star[maxm];

struct res{
    ll dis;
    int x,level;
    res(){}
    res(int _x,int _level,ll _dis):x(_x),level(_level),dis(_dis){}
    bool operator < (const res &a) const {
        return dis > a.dis;
    }
};

ll dis[maxn][15],ans;
bool vis[maxn][15];
int n,m,k,head[maxm],cnt;

void init() {
    memset(head,0,sizeof(head));
    memset(dis,inf,sizeof(dis));
    memset(vis,false,sizeof(vis));
    cnt = 0; ans = 1e18;
}

inline void add_edge(int u,int v,ll w){
    star[++cnt].to = v;
    star[cnt].nxt = head[u];
    star[cnt].w = w;
    head[u] = cnt;
}

void dijkstra(int st) { //分层图dij 
    priority_queue<res>que;
    dis[st][0] = 0;
    que.push(res(st,0,0));
    while(!que.empty()) {
        res e = que.top(); que.pop();
        int x = e.x,level = e.level;
        if ( vis[x][level] ) continue;
        vis[x][level] = true;
        for (int i = head[x]; i ; i = star[i].nxt) {
            int _to = star[i].to;
            if ( dis[x][level] + star[i].w < dis[_to][level] ) {
                dis[_to][level] = dis[x][level] + star[i].w;
                if(!vis[_to][level]) 
                    que.push(res(_to,level,dis[_to][level]));
            }
            if ( level + 1 <= k && dis[x][level] < dis[_to][level+1] ) {
                dis[_to][level+1] = dis[x][level];
                if(!vis[_to][level+1]) 
                    que.push(res(_to,level+1,dis[_to][level+1]));
            }
        }
    }
}

int main()
{
    int t; cin>>t;
    while(t--) {
        init();
        scanf("%d %d %d",&n,&m,&k);
        for (int i = 1;i<=m;i++) {
            scanf("%d %d %lld",&edge[i].u,&edge[i].v,&edge[i].w);
        }
        sort(edge+1,edge+m+1);
        int peru = -1,perv = -1;
        for (int i = 1;i<=m;i++) {
            if ( peru != edge[i].u || perv != edge[i].v) {
                add_edge(edge[i].u,edge[i].v,edge[i].w);
                peru = edge[i].u; perv = edge[i].v;
            }
        }
        dijkstra(1);
        for (int i = 0;i<=k;i++) {
            ans = min(ans,dis[n][i]);
        } 
        printf("%lld\n",ans);
    }
    return 0;
}
posted @ 2018-09-04 22:12  Nlifea  阅读(120)  评论(0编辑  收藏  举报