1. 程式人生 > >ACM-ICPC 2018 南京賽區網路預賽 L. Magical Girl Haze

ACM-ICPC 2018 南京賽區網路預賽 L. Magical Girl Haze

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

題目來源

題意:給你一個n個點,m條邊的圖,讓你最多把k條邊的邊權變為0。求從1到n的最短路。

題解:感覺OI退役以後智商就不斷下降了QAQ。還以為是什麼dp之類的。k<=10,直接建分層圖呀QAQ。每一層是正常的圖,如果要把一條邊邊權變為0,就直接從當前層走到下一層就行了,層與層之間全為邊權為0的邊。

程式碼:

#include<bits/stdc++.h>
#define pi pair<LL,int>
#define mp make_pair
#define fir first
#define sec second
using namespace std;
#define LL long long
#define INF 1e15
int NN;
struct node
{
    int begin,end,value,next;
}edge[4201010];
int U[200010],V[200010],C[200010],cnt,Head[1101010];
LL dis[1101010];
priority_queue<pi,vector<pi>,greater<pi> > q;
int read()
{
    int s=0,fh=1;char ch=getchar();
    while(ch<'0'||ch>'9'){if(ch=='-')fh=-1;ch=getchar();}
    while(ch>='0'&&ch<='9'){s=s*10+(ch-'0');ch=getchar();}
    return s*fh;
}
void addedge(int bb,int ee,int vv)
{
    edge[++cnt].begin=bb;edge[cnt].end=ee;edge[cnt].value=vv;edge[cnt].next=Head[bb];Head[bb]=cnt;
}
void dijkstra(int start)
{
    int i,u,v;
    for(i=1;i<=NN;i++)dis[i]=INF;dis[start]=0LL;
    q.push(mp(dis[start],start));
    while(!q.empty())
    {
        u=q.top().sec;q.pop();
        for(i=Head[u];i!=-1;i=edge[i].next)
        {
            v=edge[i].end;
            if(dis[v]>dis[u]+1LL*edge[i].value)
            {
                dis[v]=dis[u]+1LL*edge[i].value;
                q.push(mp(dis[v],v));
            }
        }
    }
}
int main()
{
    int T,N,M,K,j,i;
    LL ans;
    T=read();
    while(T--)
    {
        N=read();M=read();K=read();
        memset(Head,-1,sizeof(Head));cnt=1;
        for(i=1;i<=M;i++){U[i]=read();V[i]=read();C[i]=read();}
        for(j=0;j<=K;j++)
        {
            for(i=1;i<=M;i++)
            {
                addedge(U[i]+j*N,V[i]+j*N,C[i]);
            }
        }
        for(j=0;j<K;j++)
        {
            for(i=1;i<=M;i++)addedge(U[i]+j*N,V[i]+(j+1)*N,0);
        }
        NN=(K+1)*N;
        dijkstra(1);
        ans=INF;
        for(i=0;i<=K;i++)ans=min(ans,dis[(i+1)*N]);
        printf("%lld\n",ans);
    }
    return 0;
}