Magical Girl Haze(dij算法优化dp)

版权声明:本文为博主原创文章,转载请说明出处。 https://blog.csdn.net/xianpingping/article/details/82419882

There are NNN cities in the country, and MMM directional roads from uuu to v(1≤u,v≤n)v(1\le u, v\le n)v(1≤u,v≤n). Every road has a distance cic_ici​. Haze is a Magical Girl that lives in City 111, she can choose no more than KKK roads and make their distances become 000. Now she wants to go to City NNN, please help her calculate the minimum distance.

Input

The first line has one integer T(1≤T≤5)T(1 \le T\le 5)T(1≤T≤5), then following TTT cases.

For each test case, the first line has three integers N,MN, MN,M and KKK.

Then the following MMM lines each line has three integers, describe a road, Ui,Vi,CiU_i, V_i, C_iUi​,Vi​,Ci​. There might be multiple edges between uuu and vvv.

It is guaranteed that N≤100000,M≤200000,K≤10N \le 100000, M \le 200000, K \le 10N≤100000,M≤200000,K≤10,
0≤Ci≤1e90 \le C_i \le 1e90≤Ci​≤1e9. There is at least one path between City 111 and City NNN.

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

题目来源

ACM-ICPC 2018 南京赛区网络预赛

哇塞!我居然A 了。

苦于对dijstra算法的不理解,或者说理解的不是那么透彻,一直处于很难受的状态,导致这道题迟迟没有动,直到昨天上课时终于明白了每一次push进去的都是(当前通过枚举过的点(就是所谓的放到了集合中的点)所能够影响到的)当前的的点 的 最短路。

而利用最短路的思想,那我们每一次push进去的也是到达这个点目前已经换了j次的最优的情况,每一次枚举的点也都是dis(就是d[i][j])最小的点,通过这些已经算到了kk(就是算到这个点的时候已经删掉了kk条边)此时的最小的,那么当前这个状态就可以影响其他的还没有被更新的状态。每一种状态都push进去,就能算出来了。

最重要的是对jdijstra算法的理解。

AC代码:

#include<bits/stdc++.h>
using namespace std;
const int INF=0x3f3f3f3f;
const int maxn=100010;
const int maxm=200010;
int head[maxn];
int cnt;
int vis[maxn][12];
int n,m,k;
int d[maxn][12];
struct node
{
    int to,next,val;
}G[maxm];
void add(int a,int b,int val){
    G[++cnt].to=b;
    G[cnt].next=head[a];
    G[cnt].val=val;
    head[a]=cnt;
}
void init(){
    cnt=0;
    memset(head,-1,sizeof(head));
    memset(vis,false,sizeof(vis));
}
struct Node{
    int dis,to,k;
    Node(int dis,int to,int k):dis(dis),to(to),k(k){};
    bool operator < (const Node &a)const{
        return dis>a.dis;
    }
};
int dij(){
    priority_queue<Node>Q;
    for(int i=0;i<=k;i++)
        d[1][i]=0;

    Q.push(Node(0,1,0));

    while(!Q.empty()){
        Node x=Q.top();
        Q.pop();

        int to=x.to;
        int dis=x.dis;
        int kk=x.k;

        if(vis[to][k])
            continue;
        for(int i=head[to];i!=-1;i=G[i].next){
            int v=G[i].to;

          ///  cout<<"v:"<<v<<endl;

            for(int j=kk;j<=k;j++){
          ///          cout<<"&&&:"<<d[v][j]<<endl;
          ///          cout<<"Xiao:"<<d[to][j]<<endl;
                if(d[v][j]>d[to][j]+G[i].val){///不删
                    d[v][j]=d[to][j]+G[i].val;
       ///             cout<<"v:"<<v<<"   j:"<<j<<"   "<<d[v][j]<<endl;
                    Q.push(Node(d[v][j],v,j));
                }
                if( j>=1 &&d[v][j]>d[to][j-1]){///删
                    d[v][j]=d[to][j-1];
                     Q.push(Node(d[v][j],v,j));
                }
            }
        }
    }
}
int main()
{
    int t,a,b,c;
   /// freopen("r.txt","r",stdin);
    scanf("%d",&t);
    while(t--){
        init();
        scanf("%d%d%d",&n,&m,&k);
        for(int i=1;i<=m;i++){
            scanf("%d%d%d",&a,&b,&c);
            add(a,b,c);
        }
        memset(d,INF,sizeof(d));

        dij();

        int ans=999999999;
        for(int i=0;i<=k;i++){
            ans=min(d[n][i],ans);
       ///     cout<<d[n][i]<<endl;
        }
        printf("%d\n",ans);
    }
    return 0;
}
/*
1
5 6 1
1 2 2
1 3 4
2 4 3
3 4 1
3 5 6
4 5 2
*/

猜你喜欢

转载自blog.csdn.net/xianpingping/article/details/82419882