2018icpc 南京网络赛L Magical Girl Haze

原题电波~

分层图   用了堆优化的dijkstra

#include<bits/stdc++.h>
using namespace std;
#define maxn
#define maxN  100010
#define maxM  200010
#define maxK  11
#define LL long long
#define inf 1<<27
LL dis[maxN][maxK];
bool fa[maxN][maxK];
int n,m,k,tot=0;
struct ac{
   int s,v;
   LL d;
   ac(){}
   ac(int a,int b,LL c){
      s=a,v=b,d=c;
   }
}a[4*maxN];
vector<ac>q[maxN];
void updata(int v){
   //if(v==0) return ;
   if(v*2>tot) return ;
   if(v*2==tot){
      if(a[v].d>a[v*2].d){
          swap(a[v],a[v*2]);
      }
      return ;
   }
   if(a[v].d<=a[v*2].d&&a[v].d<=a[v*2+1].d) return ;
   if(a[v*2].d<a[v*2+1].d){
      swap(a[v],a[v*2]);
      updata(v*2);
   }else{
      swap(a[v],a[v*2+1]);
      updata(v*2+1);
   }
}
void push(int v){
   if(v==1){
      return ;
   }
   if(a[v].d<a[v/2].d){
      swap(a[v],a[v/2]);
      push(v/2);
   }
}
void init(){
   for(int j=1;j<=n;j++){
      q[j].clear();
   }
   tot=0;
   //memset(dis,0x3f,sizeof(dis));
   memset(fa,0,sizeof(fa));
   for(int j=0;j<=n;j++){
     for(int z=0;z<=k;z++){
       dis[j][z]=9999999999999;
     }
   }
}
void dijkstra(){
   dis[1][0]=0;
   a[++tot]=ac(0,1,0);
   while(tot){
      ac z=a[1];
      swap(a[1],a[tot]);
      tot--,updata(1);
      int x=z.v,y=z.s;
      //cout<<x<<" "<<y<<endl;
      if(fa[x][y]) continue;
      fa[x][y]=1;
      for(int j=0;j<q[x].size();j++){
         ac zz=q[x][j];
         int dd=zz.d,vv=zz.v;
         //cout<<dd<<" "<<vv<<endl;

         if(dis[x][y]+dd<dis[vv][y]){
            dis[vv][y]=dis[x][y]+dd;
            tot++;
            a[tot]=ac(y,vv,dis[vv][y]);
            push(tot);
         }
         if(y<k&&dis[x][y]<dis[vv][y+1]){
            dis[vv][y+1]=dis[x][y];
            tot++;
            a[tot]=ac(y+1,vv,dis[vv][y+1]);
            push(tot);
         }
         //cout<<dis[x][y]<<" "<<dis[vv][y]<<endl<<endl;
      }
   }
}
int main(){
    int t;
    cin>>t;
    while(t--){
       cin>>n>>m>>k;
       init();
       for(int j=0;j<m;j++){
          int x,y,z;
          scanf("%d%d%d",&x,&y,&z);
          q[x].push_back(ac(0,y,z));
       }
       dijkstra();
       LL ans=inf;
       for(int j=0;j<=k;j++){
          ans=min(ans,dis[n][j]);
       }
       cout<<ans<<endl;
    }
}

 

©️2020 CSDN 皮肤主题: 编程工作室 设计师: CSDN官方博客 返回首页
实付0元
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、C币套餐、付费专栏及课程。

余额充值