2018icpc南京网络赛L题Magical Girl Haz(dijkstra+dp)

题目链接

题意

有N个城市M条路径,可以使K条路径长度变为0,求1到N最短路

解题思路

求最短路很好求,但是题目多了一个限制条件,可以使K条路径长度变为0,这就有点麻烦了,后来想到,这也有点像01背包选与不选的感觉,求最短路的时候加个状态就可以求解了

代码

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn = 1e5+500;
struct Edge 
{
    int to,val;
};
vector<Edge> G[maxn];
typedef pair<int,int> pii;
typedef pair<ll,pii> PII;
ll dis[15][maxn];

int dijkstra(int N,int K)
{
    priority_queue<PII,vector<PII>,greater<PII> > Q;
    Q.push(PII(0,pii(1,K)));
    memset(dis,0x3f,sizeof(dis));
    dis[K][1] = 0;
    while(!Q.empty()){
        PII t = Q.top();
        Q.pop();
        int d = t.first;
        int u = t.second.first;
        int k = t.second.second;

        for(int i=0;i<G[u].size();i++){
            Edge e = G[u][i];
            if( dis[k][e.to] > dis[k][u] + e.val){
                dis[k][e.to] = dis[k][u] + e.val;
                Q.push(PII(dis[k][e.to],pii(e.to,k)));
            }
            if(k > 0 && dis[k][u] < dis[k-1][e.to]){
                dis[k-1][e.to] = dis[k][u];
                Q.push(PII(dis[k-1][e.to],pii(e.to,k-1)));
            }
        }
    }
    return dis[0][N];
}

int main(int argc, char const *argv[])
{
    int T = 0;
    scanf("%d",&T);
    int N,M,K;
    while(T--){
        scanf("%d%d%d",&N,&M,&K);
        for(int i=0;i<=N;i++){
            G[i].clear();
        }
        int a,b,c;
        for(int i=0;i<M;i++){
            scanf("%d%d%d",&a,&b,&c);
            Edge t = (Edge){b,c};
            G[a].push_back(t);
        }
        int ans = dijkstra(N,K);
        printf("%d\n",ans);
    }
    
    return 0;
}
posted @ 2018-09-29 16:36  django_lf  阅读(163)  评论(0编辑  收藏  举报