BZOJ2763 [JLOI2011]飞行路线

Description

Alice 和Bob现在要乘飞机旅行,他们选择了一家相对便宜的航空公司。该航空公司一共在n个城市设有业务,设这些城市分别标记为0到n-1,一共有m种航线,每 种航线连接两个城市,并且航线有一定的价格。Alice和Bob现在要从一个城市沿着航线到达另一个城市,途中可以进行转机。航空公司对他们这次旅行也推 出优惠,他们可以免费在最多k种航线上搭乘飞机。那么Alice和Bob这次出行最少花费多少?

Input

数据的第一行有三个整数,n,m,k,分别表示城市数,航线数和免费乘坐次数。
第二行有两个整数,s,t,分别表示他们出行的起点城市编号和终点城市编号。(0<=s,t<n)
接下来有m行,每行三个整数,a,b,c,表示存在一种航线,能从城市a到达城市b,或从城市b到达城市a,价格为c。(0<=a,b<n,a与b不相等,0<=c<=1000)
 

Output

 
只有一行,包含一个整数,为最少花费。

Sample Input

5 6 1
0 4
0 1 5
1 2 5
2 3 5
3 4 5
2 3 3
0 2 100

Sample Output

8

HINT

对于30%的数据,2<=n<=50,1<=m<=300,k=0;

 

对于50%的数据,2<=n<=600,1<=m<=6000,0<=k<=1;

 

对于100%的数据,2<=n<=10000,1<=m<=50000,0<=k<=10.

 

正解:最短路

解题报告:

  直接Dijkstra维护最短路,把每个点拆成(k+1)个,构分层图。分别表示到当前点已经免费乘坐了多少次。

  然而我调试了一个上午,最后发现原因是什么呢???

  最后知道真相的我眼泪掉下来。。。

  我的Dijkstra模板是个萎的。。。重申,我用了半年多的模板,曾经集训的若干考试、北大夏令营都一直用的,AC了无数题目的模板,是一个萎的。。。

  我必须要抽时间把所有的模板重新打一遍,当年留下了多少错误。。。

 

  1 //It is made by jump~
  2 #include <iostream>
  3 #include <cstdlib>
  4 #include <cstring>
  5 #include <cstdio>
  6 #include <cmath>
  7 #include <algorithm>
  8 #include <ctime>
  9 #include <vector>
 10 #include <queue>
 11 #include <map>
 12 #include <set>
 13 #ifdef WIN32  
 14 #define OT "%I64d"
 15 #else
 16 #define OT "%lld"
 17 #endif
 18 using namespace std;
 19 typedef long long LL;
 20 const int inf = (1<<30);
 21 const int MAXN = 200011;
 22 const int MAXM = 5000011;
 23 int n,m,k,s,t,ecnt;
 24 int first[MAXN],to[MAXM],next[MAXM],w[MAXM];
 25 int ans;
 26 bool pd[MAXN];
 27  
 28 struct node{
 29     int x,dis;
 30     bool operator < (const node & a)const {
 31     return a.dis<dis;
 32     }
 33 }a[MAXN*11];
 34  
 35 priority_queue <node> Q;
 36  
 37 inline int getint()
 38 {
 39        int w=0,q=0;
 40        char c=getchar();
 41        while((c<'0' || c>'9') && c!='-') c=getchar();
 42        if (c=='-')  q=1, c=getchar();
 43        while (c>='0' && c<='9') w=w*10+c-'0', c=getchar();
 44        return q ? -w : w;
 45 }
 46  
 47 inline void Dij(){
 48     //for(int i=1;i<=n;i++) for(int j=0;j<=k;j++) a[i][j].dis=inf,a[i][j].x=i,a[i][j].tim=j;
 49     //a[s][0].dis=0;
 50     //for(int i=0;i<=k;i++) a[s][i].dis=0; Q.push(a[s][0]);
 51     //for(int i=0;i<=k;i++) pd[s][i]=1;
 52     //pd[s][0]=1;
 53     for(int i=1;i<=n*(k+1);i++) a[i].dis=inf,a[i].x=i;//a[i].x=(i-1)%n+1;
 54     a[s].dis=0;
 55     Q.push(a[s]);
 56     int u;//int ci;
 57     while(!Q.empty()) {
 58     u=Q.top().x; //ci=Q.top().tim;
 59     Q.pop();
 60     if(pd[u]) continue;
 61     pd[u]=1;
 62     for(int i=first[u];i;i=next[i]) {
 63         int v=to[i];
 64         if(a[v].dis>a[u].dis+w[i]) {
 65         a[v].dis=a[u].dis+w[i];
 66         Q.push(a[v]);//,pd[v]=1;
 67         }
 76     }
 77     }
 78     ans=inf;
 79     for(int i=0;i<=k;i++) ans=min(ans,a[i*n+t].dis);
 80     //for(int i=0;i<=k;i++) ans=min(a[t][i].dis,ans);
 81     printf("%d",ans);
 82 }
 83  
 84 inline void link(int x,int y,int z){//单向边
 85     next[++ecnt]=first[x]; first[x]=ecnt; to[ecnt]=y; w[ecnt]=z;
 86 }
 87  
 88 inline void work(){
 89     n=getint(); m=getint(); k=getint();
 90     s=getint()+1; t=getint()+1; int x,y,z;
 91     for(int i=1;i<=m;i++) {//必须事先连边
 92     x=getint()+1; y=getint()+1; z=getint();
 93     for(int j=0;j<=k;j++) {//拆点
 94         link(n*j+x,j*n+y,z); link(n*j+y,n*j+x,z);
 95         if(j<k) { link(n*j+x,(j+1)*n+y,0); link(j*n+y,n*(j+1)+x,0); }
 96     }
 97     }
 98     Dij();
 99 }
100  
101 int main()
102 {
103   work();
104   return 0;
105 }

 

posted @ 2016-07-30 12:18  ljh_2000  阅读(219)  评论(0编辑  收藏  举报