最短路,然后可以有多次免费的机会,不难写,但是最短路这次试着用指针写果然快了点,一开始看错数据范围数组开太大tle;

----------------------------------------------------------------------------------------------

#include<cstdio>
#include<cstring>
#include<queue>
#include<iostream>
#include<algorithm>
using namespace std;
#define rep(i,n) for(int i=1;i<=n;i++)
#define clr(x,c) memset(x,c,sizeof(x))
#define adde(u,v,w) add(u,v,w),add(v,u,w)


int read(){
   int x=0;
   char c=getchar();
   int f=1;
   while(!isdigit(c)){
      if(c=='-') f=-1;
      c=getchar();
   }
   while(isdigit(c)){
      x=x*10+c-'0';
      c=getchar();
   }
   return x*f;
}


struct edge{
    int to,d;
    edge*next;
};
edge*pt,edges[50005*2];
edge*head[10005];
int n,m,k,s,t;
int dis[10005][15];


struct node{
 int x,k,d;
 node(int _x,int _k,int _d):x(_x),k(_k),d(_d){};
 bool operator<(const node&rhs)const{
   return d>rhs.d;}
};
priority_queue<node>q;


void add(int u,int v,int w){
   pt->to=v;
   pt->d=w;
   pt->next=head[u];
   head[u]=pt++;
}


void dijkstra(){
   clr(dis,0x3f);
   clr(dis[s],0);
   q.push(node(s,0,0));
   rep(i,k)
        q.push(node(s,i,0));
   while(!q.empty()){
    node o=q.top();
    q.pop();
    if(o.d!=dis[o.x][o.k]) continue;
    for(edge*e=head[o.x];e;e=e->next){
        int to=e->to;
        if(dis[o.x][o.k]+e->d<dis[to][o.k]){
             dis[to][o.k]=dis[o.x][o.k]+e->d;
             q.push(node(to,o.k,dis[to][o.k]));
         }
        if(dis[o.x][o.k]<dis[to][o.k+1]&&o.k<k){
             dis[to][o.k+1]=dis[o.x][o.k];
             q.push(node(to,o.k+1,dis[to][o.k+1]));
        }
     }
   }
}
int main(){
   /*freopen("test.in","r",stdin);
   freopen("test.out","w",stdout);*/
   scanf("%d%d%d%d%d",&n,&m,&k,&s,&t);
   s++,t++;
   clr(head,0);
   pt=edges;
   rep(i,m){
      int u=read(),v=read(),w=read();
      u++,v++;
      adde(u,v,w);
   }
   /*rep(i,n){
          printf("%d\n",i);
         for(edge*e=head[i];e;e=e->next){
               printf("%d %d\n",e->to,e->d);
         }
     }*/
   dijkstra();
   int ans=dis[t][0];
   rep(i,k){
        ans=min(ans,dis[t][i]);
    }
    printf("%d\n",ans);
    //fclose(stdin);fclose(stdout);
    return 0;
}

----------------------------------------------------------------------------------------------

2763: [JLOI2011]飞行路线

Time Limit: 10 Sec  Memory Limit: 128 MB
Submit: 1448  Solved: 551
[Submit][Status][Discuss]

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.

 

 

Source

 
[Submit][Status][Discuss]