标签:
Description
Input
Output
Sample Input
5 8 5 1 2 2 1 5 3 1 3 4 2 4 7 2 5 6 2 3 5 3 5 1 4 5 1 2 2 3 4 3 4 1 2 3 1 3 4 2 3 2 1 1
Sample Output
1 -1
题意:给你交通路线以及Kiki家能到达的车站,让你求出Kiki到达目的地的最短路,如果不能到达,就输出-1;
思路:对于多起点一个终点的问题,可以把起点简化成一个起点,即:将Kiki家视为真正的起点,然后把他家到达每一个能到达的起点的距离看成是0,这样就能缩短时间复杂度。对于多起点多终点的情况,可以将多个起点连在同一个假想的起点上,并且把距离置为0,终点也一样。
注意:本题标明交通路线是directed,即:有向图
代码如下:
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cstring>
#include <string>
#include <cmath>
#include <cstdlib>
using namespace std;
const int INF=0x3f3f3f3f;
const int N=1010;
int mp[N][N];
int dis[N];
int vis[N];
int m;
int n;
int dijstra()
{
memset(dis,0x3f,sizeof(dis));
memset(vis,0,sizeof(vis));
dis[0]=0;
for(int i=1;i<=n;i++)
{
int k=0;
int mini=INF;
for(int j=1;j<=n;j++)
{
if(!vis[j]&&mini>dis[j])
mini=dis[k=j];
}
vis[k]=1;
if(k==m) return dis[m];
for(int j=1;j<=n;j++)
{
if(vis[j]||mp[k][j]==INF) continue;
dis[j]=min(dis[j],dis[k]+mp[k][j]);
}
}
return dis[m];
}
int main()
{
int s; //已修好的路有几条
while(~scanf("%d%d%d",&n,&s,&m)) //终点是m,最远的点是n
{
memset(mp,INF,sizeof(mp));
while(s--)
{
int a,b,c;
scanf("%d%d%d",&a,&b,&c);
if(mp[a][b]>c)
mp[a][b]=c;
}
int d; //起点个数
scanf("%d",&d);
while(d--)
{
int x; //起点
scanf("%d",&x);
mp[0][x]=0; //将能做起点的均与‘0’相连,并且都赋值0,不影响后面的操作,保证只有一个起点‘0‘
}
int k=dijstra();
if(k==INF) printf("-1\n");
else