某街区有R条道路,N个路口,道路可以双向通过,问1路口到N路口的次短距离同一条路可以走多次
以下是一个求k短路的算法,但是会超内存,因为队列放不下这么多结构体。但题目要求的是次短路,所以其实还是可以进行优化的。请看第二段代码
#include<cstdio>
#include<queue>
#include<cstring>
#include<iostream>
using namespace std;
int cnt,n;
int head[5009];
struct node
{
int v,next,w;
}s[200009];
struct re
{
int v,w;
re(){
}
re(int v,int w):v(v),w(w){
}
bool operator< (const re& other) const
{
return w>other.w;
}
};
priority_queue<re> que;
void add(int u,int v,int w)
{
s[cnt].v=v;
s[cnt].w=w;
s[cnt].next=head[u];
head[u]=cnt++;
s[cnt].v=u;
s[cnt].w=w;
s[cnt].next=head[v];
head[v]=cnt++;
}
void k_min()
{
int k=2;
while(!que.empty()) que.pop();
que.push(re(1,0));
while(!que.empty())
{
re tp=que.top();
que.pop();
//cout<<tp.v<<" "<<tp.w<<endl;
if(tp.v==n)
{
k--;
if(k==0)
{
printf("%d\n",tp.w);
return;
}
}
for(int i=head[tp.v];i!=-1;i=s[i].next)
{
que.push(re(s[i].v,tp.w+s[i].w));
}
}
}
int main()
{
int r,u,v,w;
//freopen("t.txt","r",stdin);
while(scanf("%d%d",&n,&r)!=EOF)
{
cnt=0;
memset(head,-1,sizeof(head));
while(r--)
{
scanf("%d%d%d",&u,&v,&w);
//cout<<u<<" "<<v<<" "<<w<<endl;;
add(u,v,w);
}
k_min();
}
return 0;
}
正确不超内存的代码:
#include<cstdio>
#include<queue>
#include<cstring>
#include<iostream>
#define inf 1000000000
using namespace std;
int cnt,n;
int head[5009];
int dis[5009],dis2[5009];
struct node
{
int v,next,w;
}s[200009];
struct re
{
int v,w;
re(){
}
re(int v,int w):v(v),w(w){
}
bool operator< (const re& other) const
{
return w>other.w;
}
};
priority_queue<re> que;
void add(int u,int v,int w)
{
s[cnt].v=v;
s[cnt].w=w;
s[cnt].next=head[u];
head[u]=cnt++;
s[cnt].v=u;
s[cnt].w=w;
s[cnt].next=head[v];
head[v]=cnt++;
}
void k_min()
{
int k=2;
while(!que.empty()) que.pop();
que.push(re(1,0));
for(int i=1;i<=n;i++)
dis[i]=dis2[i]=inf;
dis[1]=0;
while(!que.empty())
{
re tp=que.top();
que.pop();
if(tp.w>dis2[tp.v]) continue;
for(int i=head[tp.v];i!=-1;i=s[i].next)
{
int s1=tp.w+s[i].w;
if(s1<dis[s[i].v])
{
swap(dis[s[i].v],s1);
que.push(re(s[i].v,dis[s[i].v]));
}else if(s1>dis[s[i].v]&&s1<dis2[s[i].v])
{
dis2[s[i].v]=s1;
que.push(re(s[i].v,dis2[s[i].v]));
}
que.push(re(s[i].v,tp.w+s[i].w));
}
}
printf("%d\n",dis2[n]);
}
int main()
{
int r,u,v,w;
//freopen("t.txt","r",stdin);
while(scanf("%d%d",&n,&r)!=EOF)
{
cnt=0;
memset(head,-1,sizeof(head));
while(r--)
{
scanf("%d%d%d",&u,&v,&w);
//cout<<u<<" "<<v<<" "<<w<<endl;;
add(u,v,w);
}
k_min();
}
return 0;
}