题目链接
这题是个标准的求最短路径的题目,不过并不是单一起点单一终点,我的解决方法就是再多加一个虚拟起点,将这个虚拟起点与各个起点的距离为0,然后再加一个虚拟终点,将这个虚拟终点到各个终点的距离设置为0,然后求虚拟起点到虚拟终点的最短路径就可以了,这样的处理就转换为单起点单终点的处理,就和畅通工程续问题一样了。
写代码的时候要注意细节,否则很容易掉进循环出不来,注意这个站点是从0开始还是从1开始,注意站点数目的上限值,注意vis的更新,inf的定义,都非常重要,注意初始化imap初始化应该是inf,dis初始化也是inf,还有这句灵魂代码千万不要打错,我就手误打错好几次了,而且检查了好多遍才检查出来
if(imap[start][i]!=inf)
dis[i]=min(dis[i],imap[start][i]+dis[start]);
最后我们上代码
#include<bits/stdc++.h>
#define inf 0x7FFFFFFF
using namespace std;
int imap[1005][1005],vis[1005],dis[1005];
int main()
{
int t,s,d,a,b,time,n,start,targe,x,imin,inext;
while(scanf("%d%d%d",&t,&s,&d)!=EOF)
{
for(int i=0;i<1005;i++)
{
vis[i]=1;
dis[i]=inf;
for(int j=0;j<1005;j++)
imap[i][j]=inf;
}
n=-1;
while(t--)
{
scanf("%d%d%d",&a,&b,&time);
imap[a][b]=min(imap[a][b],time);
imap[b][a]=imap[a][b];
n=max(a,max(b,n));
}
start=0;
targe=n+1;
n+=1;
while(s--)
scanf("%d",&x),imap[x][start]=imap[start][x]=0;
while(d--)
scanf("%d",&x),imap[x][targe]=imap[targe][x]=0;
vis[start]=0;
dis[start]=0;
while(start!=targe)
{
imin=inf;
for(int i=0;i<=n;i++)
{
if(vis[i]==0)
continue;
if(imap[start][i]!=inf)
dis[i]=min(dis[i],imap[start][i]+dis[start]);
if(vis[i]&&dis[i]<imin)
{
inext=i;
imin=dis[i];
}
}
if(imin==inf)
break;
start=inext;
vis[start]=0;
}
if(dis[targe]==inf)
puts("-1");
else
printf("%d\n",dis[targe]);
}
return 0;
}