码迷,mamicode.com
首页 > 其他好文 > 详细

luogu P4568 [JLOI2011]飞行路线

时间:2018-10-10 23:40:09      阅读:183      评论:0      收藏:0      [点我收藏+]

标签:mat   eof   getc   while   operator   gis   void   memset   ons   

传送门

看到免费次数\(k\)最多只有10,可以考虑构建\(k+1\)层的分层图,即每一层正常连边,上下两层对应点连边权为0的单向边,最后对所有层里面的\(di_t\)\(\max\)救星了

#include<bits/stdc++.h>
#define LL long long
#define il inline
#define re register
#define db double
#define eps (1e-5)

using namespace std;
const int N=10000+10,M=50000+10;
il LL rd()
{
    re LL x=0,w=1;re char ch;
    while(ch<'0'||ch>'9') {if(ch=='-') w=-1;ch=getchar();}
    while(ch>='0'&&ch<='9') {x=(x<<3)+(x<<1)+(ch^48);ch=getchar();}
    return x*w;
}
int to[(M*22)<<1],nt[(M*22)<<1],w[(M*22)<<1],hd[N*11],tot=1;
il void add(int x,int y,int z){++tot,to[tot]=y,nt[tot]=hd[x],w[tot]=z,hd[x]=tot;}
struct node
{
  int x,d;
  bool operator < (const node &bb) const {return d>bb.d;}
};
int n,m,kk,ss,tt,ed,di[N*11];

int main()
{
  n=rd(),m=rd(),kk=rd(),ss=rd(),tt=rd();
  for(int i=1;i<=m;i++)
    {
      int x=rd(),y=rd(),z=rd();
      for(int j=0;j<=kk;j++) add(x+j*n,y+j*n,z),add(y+j*n,x+j*n,z);
      for(int j=0;j<kk;j++) add(x+j*n,y+(j+1)*n,0),add(y+j*n,x+(j+1)*n,0);
    }
  ed=n*(kk+1);
  for(int j=0;j<=kk;j++) add(tt+j*n,ed,0);
  memset(di,63,sizeof(di));
  di[ss]=0;
  priority_queue<node> q;
  q.push((node){ss,0});
  while(!q.empty())
    {
      int x=q.top().x,d=q.top().d;
      q.pop();
      if(d>di[x]) continue;
      for(int i=hd[x];i;i=nt[i])
        {
          int y=to[i];
          if(di[y]>di[x]+w[i])
            {
              di[y]=di[x]+w[i];
              q.push((node){y,di[y]});
            }
        }
    }
  printf("%d\n",di[ed]);
  return 0;
}

luogu P4568 [JLOI2011]飞行路线

标签:mat   eof   getc   while   operator   gis   void   memset   ons   

原文地址:https://www.cnblogs.com/smyjr/p/9769434.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!