(bzoj 2763 [JLOI2011]飞行路线)<分层图>

来源:互联网 发布:123d打印软件 编辑:程序博客网 时间:2024/05/21 14:57

题目

Time Limit: 10 Sec
Memory Limit: 128 MB

Description

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

Input

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

题解

如果你不懂分层图,那么请移步到一个靠谱的博客
如果你懂分层图而不会做这道题,那么请考虑退役
That'all.

还是可怜可怜你
好心给你贴个代码吧,唉(想父亲一样沉重的叹息)

代码

// by spli#include<iostream>#include<cstring>#include<cstdio>#include<algorithm>#include<queue>using namespace std;const int M=1200100;int n,m,k,s,t;struct node{    int to,nxt,val;}e[M*2];int head[M],cnt;struct dist{    int x,d;};priority_queue<dist>q;int dis[M];bool vis[M];bool operator < (dist a,dist b){    if(a.d==b.d)return a.x<b.x;    return a.d>b.d;}void add(int f,int t,int v){    cnt++;    e[cnt]=(node){t,head[f],v};    head[f]=cnt;}void dij(){    memset(dis,0x3f3f3f3f,sizeof(dis));    q.push((dist){s,0});    dis[s]=0;    while(!q.empty()){        dist p=q.top();        q.pop();        if(vis[p.x]) continue;        int u=p.x;        vis[u]=1;        for(int i=head[u];i!=-1;i=e[i].nxt){            int v=e[i].to;            if(dis[v]>dis[u]+e[i].val){                dis[v]=dis[u]+e[i].val;                q.push((dist){v,dis[v]});            }        }    }    int ans=0x3f3f3f3f;    for(int i=0;i<=k;++i)        ans=min(ans,dis[t+i*n]);    cout<<ans<<endl;    return;}int main(){    memset(head,-1,sizeof(head));    scanf("%d%d%d%d%d",&n,&m,&k,&s,&t);    int a,b,c;    for(int i=1;i<=m;++i){        scanf("%d%d%d",&a,&b,&c);        for(int j=0;j<=k;++j){            add(a+j*n,b+j*n,c);            add(b+j*n,a+j*n,c);            if(i!=k){                add(a+j*n,b+(j+1)*n,0);                add(b+j*n,a+(j+1)*n,0);            }        }    }    dij();    return 0;}
原创粉丝点击