您的位置:首页 > 其它

HDU 4725 The Shortest Path in Nya Graph(优先队列+dijkstra)

2015-04-23 20:14 344 查看
题意:n个点、m条边、层与层之间的花费为c,给出每个点所在层(同一层的点联通花费为0),m条边每条边的花费,求1到n的最小花费;

思路:第一反应就是优先队列的dijkstra,层与层之间建边,点与点之间建边,层与包含点之间建边,点与相邻层之间建边;练习一下优先队列dijkstra和邻接表;

#include<cstdio>
#include<cstring>
#include<algorithm>
#include<queue>
using namespace std;
#define INF 0x3f3f3f3f
int pp[500010],vv[500010],dist[500010];
int vis[500010],cnt,n,m,c;
int lay[500010];
struct Node
{
int u,v,w;
int next;
}edge[500010];//邻接表
struct node
{
int pos,dd;
bool operator <(const node&xx)const
{
return dd>xx.dd;
}
}cur,now;
void addedge(int u,int v,int w)//邻接表
{
cnt++;
edge[cnt].v=v;
edge[cnt].w=w;
edge[cnt].next=pp[u];
pp[u]=cnt;
}
priority_queue<node> q;
void dijkstra()
{
int i,j,k,u,v,w;
memset(vis,0,sizeof(vis));
while(!q.empty()) q.pop();
dist[1]=0;
cur.pos=1;cur.dd=0;
q.push(cur);
while(!q.empty())
{
now=q.top();
q.pop();
u=now.pos;
if(vis[u]) continue;
vis[u]=1;
for(i=pp[u];i;i=edge[i].next)
{
v=edge[i].v;
w=edge[i].w;
if(!vis[v]&&dist[v]>dist[u]+w)
{
dist[v]=dist[u]+w;
cur.pos=v;cur.dd=dist[v];
q.push(cur);
}
}
}
}
int main()
{
int i,j,k,u,v,w,t,temp;
scanf("%d",&t);
for(k=1;k<=t;k++)
{
scanf("%d%d%d",&n,&m,&c);
memset(pp,0,sizeof(pp));
memset(vv,0,sizeof(vv));
memset(dist,INF,sizeof(dist));
cnt=0;
for(i=1;i<=n;i++)
{
scanf("%d",&u);
lay[i]=u;
vv[u]=1;
}
for(i=1;i<n;i++)
{
if(vv[i]&&vv[i+1])//相邻层之间建边
{
addedge(n+i,n+i+1,c);//使用n个点以外的编号
addedge(n+i+1,n+i,c);
}
}
for(i=1;i<=n;i++)
{
addedge(lay[i]+n,i,0);//层与所包含点建边
if(lay[i]>1) addedge(i,lay[i]+n-1,c);//点与相邻层建边
if(lay[i]<n) addedge(i,lay[i]+n+1,c);//点与相邻层建边
}
for(i=1;i<=m;i++)
{
scanf("%d%d%d",&u,&v,&w);//点与点之间建边
addedge(u,v,w);
addedge(v,u,w);
}
dijkstra();
temp=dist
;
printf("Case #%d: ",k);
if(temp==INF) printf("-1\n");
else printf("%d\n",temp);
}
return 0;
}


  
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: