您的位置:首页 > 产品设计 > UI/UE

HDU 4396 More lumber is required [至少经过K边最短路]

2012-09-25 14:13 495 查看
  求至少经过K条边,到达终点的最短路(K<=50)。 

  K比较小,先用Bellman求出走50步到达每个点的最短路,然后把50步的可达点加到队列里SPFA即可。

  题解是直接二维最短路的,不过好像比bellman+spfa慢。。目前排在HDOJ第一。。

  

#include <string.h>
#include <stdio.h>
#include <queue>
#define MAXN 5005
#define MAXE 200005
#define INF 0x3f3f3f3f
struct edge{
int u,v,n,w;
}e[MAXE];
int first[MAXN],es;
int tu,tv,tw;
int s,t,k,n,m;
void addedge(int u,int v,int w){
e[es].u=u,e[es].v=v,e[es].w=w;
e[es].n=first[u],first[u]=es++;
}
int dd[52][MAXN];
void bellman(){
memset(dd,0x3f,sizeof dd);
dd[0][s]=0;
for(int i=1;i<=k;i++)for(int j=0;j<es;j++)
if(dd[i][e[j].v]>dd[i-1][e[j].u]+e[j].w)
dd[i][e[j].v]=dd[i-1][e[j].u]+e[j].w;
}
bool inq[MAXN];
int spfa(){
std::queue<int> q;
memset(inq,0,sizeof inq);
for(int i=1;i<=n;i++)
if(dd[k][i]!=INF)q.push(i);
while(!q.empty()){
int u=q.front();q.pop();
inq[u]=0;
for(int i=first[u];i!=-1;i=e[i].n){
int v=e[i].v;
if(dd[k][v]>dd[k][u]+e[i].w){
dd[k][v]=dd[k][u]+e[i].w;
if(!inq[v])q.push(v),inq[v]=1;
}
}
}
return dd[k][t]==INF?-1:dd[k][t];
}
int main(){
//freopen("test.in","r",stdin);
while(scanf("%d%d",&n,&m)!=EOF){
memset(first,-1,sizeof first);es=0;
for(int i=0;i<m;i++){
scanf("%d%d%d",&tu,&tv,&tw);
addedge(tu,tv,tw);
addedge(tv,tu,tw);
}
scanf("%d%d%d",&s,&t,&k);
k=(k+9)/10;
bellman();
printf("%d\n",spfa());
}
return 0;
}


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