您的位置:首页 > 其它

【Heap-Dijkstra】【分层图】bzoj2763 [JLOI2011]飞行路线

2014-09-30 10:44 417 查看
建立k+1张图,

在图与图之间,若在原图中x到y有边,就建立从 第i层的x 到 i+1层的y 建边,权值为0。代表一次免费机会。

由于一旦到了第i+1层的图里,则无法回到之前的层,所以免费最多只有k次。符合题意。

spfa会TLE。

#include<cstdio>
#include<queue>
#include<cstring>
#include<algorithm>
using namespace std;
int n,m,k,sta,end,x,y,z,ans=2147483647;
struct Point{int d,u;Point(const int &a,const int &b){d=a;u=b;}Point(){}};
bool operator < (const Point &a,const Point &b){return a.d>b.d;}
priority_queue<Point>q;
bool vis[110001];
int d[110001],first[2100001],next[2100001],v[2100001],w[2100001],en;
void AddEdge(const int &U,const int &V,const int &W)
{v[++en]=V; w[en]=W; next[en]=first[U]; first[U]=en;}
void dijkstra(const int &s)
{
memset(vis,false,sizeof(vis));
memset(d,0x7f,sizeof(d)); d[s]=0;
q.push(Point(0,s));
while(!q.empty())
{
Point x=q.top(); q.pop();
if(!vis[x.u])
{
vis[x.u]=true;
for(int i=first[x.u];i;i=next[i])
if(d[v[i]]>d[x.u]+w[i])
{
d[v[i]]=d[x.u]+w[i];
q.push(Point(d[v[i]],v[i]));
}
}
}
}
int main()
{
scanf("%d%d%d%d%d",&n,&m,&k,&sta,&end);
for(int i=1;i<=m;i++)
{
scanf("%d%d%d",&x,&y,&z);
AddEdge(x,y,z);
AddEdge(y,x,z);
for(int j=1;j<=k;j++)
{
AddEdge(x+(j-1)*n,y+j*n,0);
AddEdge(y+(j-1)*n,x+j*n,0);
AddEdge(x+j*n,y+j*n,z);
AddEdge(y+j*n,x+j*n,z);
}
}
dijkstra(sta);
for(int i=0;i<=k;i++) ans=min(ans,d[end+i*n]);
printf("%d\n",ans);
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: