题目链接: 一个人的旅行
思路
虽然只是一道普通的最短路,但是还是有可以借鉴的点。一个是原来的做法就是跑多次最短路,但是今晚上翻了翻别人的做法,发现其实可以跑一次dijkstra,就是把家设为0点,然后家到车站的距离设置为0,然后我们只要求家到每个点的最短路径就可以了。第二点是又强化了dijkstra的堆优化,一次过了好激动。
#include <bits/stdc++.h>
using namespace std;
const int inf = 0x3f3f3f3f;
const int maxn = 3000;
struct edge{
int to,next,w;
}edge[maxn];
struct node{
int cost,to;
};
int tot,head[maxn];
typedef pair<int,int>P;
int dist[maxn],vis[maxn];
void add(int u,int v,int cost){
edge[++tot].to = v;
edge[tot].w = cost;
edge[tot].next = head[u];
head[u] = tot;
}
void dijkstra()
{
dist[0] = 0;
priority_queue<P,vector<P>,greater<P> >P1;
P1.push({0,0});
while(!P1.empty())
{
P p = P1.top();
P1.pop();
int v = p.second;
for(int k = head[v] ; k != -1; k = edge[k].next)
{
int to = edge[k].to;
int w = edge[k].w;
if(dist[to] > dist[v] + w)
{
dist[to] = dist[v] + w;
P1.push({dist[to],to});
}
}
}
}
int main()
{
int n,S,D,A,B,C;
while(cin >> n >> S >> D)
{
memset(dist,inf,sizeof(dist));
memset(head,-1,sizeof(head));
tot = 0;
for(int i = 1; i <= n; ++i )
{
cin >> A >> B >> C;
add(A,B,C);
add(B,A,C);
}
for(int i = 1; i <= S; ++i)
{
cin >> A;
add(0,A,0);
add(A,0,0);
}
dijkstra();
int miner = inf;
for(int i = 1;i <= D; ++i)
{
cin >> A;
miner = min(miner,dist[A]);
}
cout << miner << endl;
}
}
2.多次spfa()
#include <bits/stdc++.h>
using namespace std;
const int inf = 0x3f3f3f3f;
struct Edge{
int to,w,next;
}Edge[10001];
int vis[10001],dist[10001],head[10001];
int spfa(int s)
{
vis[s] = 1;
dist[s] = 0;
int k,v,u;
queue<int>Q;
Q.push(s);
while(!Q.empty())
{
u = Q.front();
Q.pop();
vis[u] = 0;
for(k = head[u]; k != -1; k = Edge[k].next)
{
int v = Edge[k].to;
int w = Edge[k].w;
if(dist[v] > dist[u] + w)
{
dist[v] = dist[u] + w;
if(!vis[v])
{
vis[v] = 1;
Q.push(v);
}
}
}
}
}
int main()
{
int n,m,k,i,s[10001],a[10001],j,A,B,W;
while(scanf("%d %d %d",&n,&m,&k) != EOF)
{
memset(dist,inf,sizeof(dist));
memset(head,-1,sizeof(head));
memset(vis,0,sizeof(vis));
for(i = 1; i <=2* n ; i++)
{
scanf("%d %d %d",&A,&B,&W);
Edge[i].to = B;
Edge[i].w = W;
Edge[i].next = head[A];
head[A] = i;
i++;
Edge[i].to = A;
Edge[i].w = W;
Edge[i].next = head[B];
head[B] = i;
}
for(i = 1; i <= m ; i++)
{
scanf("%d",&s[i]);
}
for(i = 1; i <= k ; i++)
{
scanf("%d",&a[i]);
}
int miner = inf;
for(i = 1; i <= m ;i++)
{
memset(dist,inf,sizeof(dist));
memset(vis,0,sizeof(vis));
spfa(s[i]);
for(j = 1; j <= k ; j++)
{
miner = min(miner , dist[a[j]]);
}
}
printf("%d\n",miner);
}
}
}