/*
题目大意:
给你一个有向图,一个起点集合,一个终点,求最短路。。。。
解题思路:
1.自己多加一个超级源点,把起点集合连接到超级源点上,
然后将起点与超级源点的集合的路径长度设为0,这样就称为一个n+1个点的单源最短路算法。。。。。
2.反向图+终点的Dijkstra,然后记录最小值。
*/
#include<iostream>
#include<cstdio>
#include<cstring>
#include<queue>
#include<algorithm>
using namespace std;
const int maxn=1002;
const int INF=1<<29;
int map[maxn][maxn],n,m,e,dis[maxn],vis[maxn];
struct Node
{
int v,next,w;
bool operator < (const Node &a) const
{
return w > a.w;
}
} Edge[2000002],t1,t2;
int dijstra(int st,int ed)
{
priority_queue<Node>q;
memset(vis,0,sizeof(vis));
for(int i=0; i<=n; i++)
{
dis[i]=INF;
if(map[st][i]<dis[i])
{
dis[i] = map[st][i];
t1.w = dis[i];
t1.v = i;
q.push(t1);
}
}
dis[st]=0;//此句没加错了2次,囧~~~
vis[st] = 1;
while(!q.empty())
{
t1 = q.top();
q.pop();
int u = t1.v;
if(vis[u]) continue;
vis[u] = 1;
for(int v=0; v<=n; v++)
{
if(!vis[v])
{
if(dis[v]>dis[u]+map[u][v])
{
dis[v] =dis[u]+map[u][v];
t2.v = v;
t2.w = dis[v];
q.push(t2);
}
}
}
}
if(dis[ed]>=INF)return -1;
return dis[ed];
}
int main()
{
while(scanf("%d%d%d",&n,&m,&e)!=EOF)
{
int i,j,s,a,b,w,ans=1<<29;
for(i=0;i<=n;i++)
{
for(j=0;j<=n;j++)
{
map[i][j]=INF;
}
map[i][i]=0;
}
for(i=1;i<=m;i++)
{
scanf("%d%d%d",&a,&b,&w);
map[a][b]=min(map[a][b],w);
}
scanf("%d",&w);
for(i=1;i<=w;i++)
{
scanf("%d",&s);
map[0][s]=0;
}
printf("%d\n",dijstra(0,e));
}
return 0;
}
hdu 2680 简单 dijstra
最新推荐文章于 2021-04-20 21:37:58 发布