第一次提交超时了;
终点只有一个,起点有多个,想多次Dijkstra来着,结果毫无悬念地超时了
然后想起周三刘学长说多的一点------貌似就是超级汇点(为了借题需要虚构出的一个顶点)
使编号为0的虚拟超级汇点,到各个起点有一条单向的,权值无为0的边
然后从超级汇点开始查找,这样只需一次Dijkstra就OK了
#include<iostream>
using namespace std;
const int N=1005;
const int maxint=100000000;
int map[N][N],
n;
int Dijkstra(int now,int end)
{
int used[N],dis[N];
for(int i=0;i<=n;i++)
{
dis[i]=map[now][i];
used[i]=0;
}
dis[now]=0;
used[now]=1;
for(int i=0;i<n;i++)
{
int max=maxint;
int u=now;
for(int j=0;j<=n;j++)
if(!used[j]&&dis[j]<max)
{
u=j;
max=dis[j];
}
used[u]=1;
for(int j=0;j<=n;j++)
if(!used[j]&&map[u][j]<maxint)
{
int min=dis[u]+map[u][j];
if(min<dis[j])
{
dis[j]=min;
}
}
}
return dis[end];
}
int main ()
{
int s,e,v,m,end;
while(scanf("%d%d%d",&n,&m,&end)!=EOF)
{
for(int i=0;i<=n;i++)
for(int k=0;k<=n;k++)
map[i][k]=maxint;
for(int i=1;i<=m;i++)
{
scanf("%d%d%d",&s,&e,&v);
if(map[s][e]>v)
map[s][e]=v;
}
int snum,start,ans=maxint;
scanf("%d",&snum);
for(int i=1;i<=snum;i++)
{
scanf("%d",&start);
map[0][start]=0;
}
ans=Dijkstra(0,end);
if(ans==maxint)
printf("-1\n");
else
printf("%d\n",ans);
}
return 0;
}