hdu 2680 简单 dijstra

/*
题目大意:
给你一个有向图,一个起点集合,一个终点,求最短路。。。。
解题思路:
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)