Each case begins with three integers n, m and s,(n<1000,m<20000,1=<s<=n) n stands for the number of bus stations in this city and m stands for the number of directed ways between bus stations .(Maybe there are several ways between two bus stations .) s stands for the bus station that near Kiki’s friend’s home.
Then follow m lines ,each line contains three integers p , q , t (0<t<=1000). means from station p to station q there is a way and it will costs t minutes .
Then a line with an integer w(0<w<n), means the number of stations Kiki can take at the beginning. Then follows w integers stands for these stations.
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
1 -1
题意是先输入三个数,分别表示总共公交站台个数n,公交车路线个数m,目的地的公交站台s,然后输入m个公交线路,一对边和权值,然后输入一个数w表示最初能去的公交站台的个数,接下来w个数分别是最初可以到达的公交站台;求到达目的地s的最短时间(最小权值)。题目一看就知道是最短路,不过显然这题与别的题目有点不一样的是初始站台很多个,目标站台只有一个,这种情况对于像我这种只会spfa的弱鸡可怎么办好,如果把所有的初始站台都来一遍spfa那最坏情况999次,在乘以每一次的spfa时间复杂度那真是够我受的了,于是,机智的弱鸡想到了一个好办法,这题不就是求很多源点到一个点的最短路径吗,我们如果把题目给我们的初始边反转,反过来不就是求目标点到所有源点的最短路径吗?所以这样子就直接把问题化简为了只调用一次spfa,正在弱鸡兴奋之余,一股脑敲完代码就提交了,于是一股脑的脑残TLE了,弱鸡想想,哎哟,不对哟!怎么可能?!!我可是把最坏情况都优化到了调用spfa一次呢!!!为啥还是TLE呢5555~~~
于是,弱鸡因此发现了一个重大发现!弱鸡去网上看了看别人用spfa过的代码,看看之后觉得,嗯?难道是杭电oj故意刁难我?于是一股脑在交了3次。于是。。。结果大家懂的。
唉,弱鸡只好细心比对代码,一个个比对一个个比对呀!发现只不过人家写的队列而弱鸡用的栈(还是写的模拟),由于还不会直接用STL的队列和栈,于是弱弱的我只好把模拟栈改成的模拟对列,结果大出我所料!!!!!!弱鸡简直是兴奋极了!!!!一个顺序的不同却直接造成了时间的巨大差异。这足以说明spfa还是具有偶然性,(并不能说明只能用队列写,有的情况是只能用栈不能用队列!)
所以以后写spfa的时候弱鸡会注意这些的,同时还得去读读上次某学长给的人品导论,要是比赛遇到了只求人品好一遍ac!
#include <iostream>
#include <cstdio>
#include <cstring>
#include<algorithm>
#define max0 999999
using namespace std;
int dl[1000000],cc[1005][1005],dis[1005];
bool vis[1005];
int min0(int a,int b)
{
return a>b?b:a;
}
void spfa(int s,int n)
{
int r=0,l=0;
memset(dl,0,sizeof(dl));
memset(vis,1,sizeof(vis));
for(int i=1;i<=n;i++)
dis[i]=max0;
dis[s]=0;
dl[r++]=s;
while(l<r)
{
int x=dl[l];
vis[x]=1;
for(int i=1;i<=n;i++)
{
if(cc[x][i]!=max0)
{
if(dis[i]>dis[x]+cc[x][i])
{
dis[i]=dis[x]+cc[x][i];
if(vis[i])
{
dl[r++]=i;
vis[i]=0;
}
}
}
}
l++;
}
}
int main()
{
int n,m,s;
while(~scanf("%d%d%d",&n,&m,&s))
{
int a,b,c;
for(int i=1;i<=n;i++)
for(int j=1;j<=n;j++)
if(i!=j)cc[i][j]= max0;else cc[i][j]=0;
for(int i=0;i<m;i++)
{
scanf("%d%d%d",&a,&b,&c);
if(c<cc[b][a])
cc[b][a]=c;
}
spfa(s,n);
int q,sum=max0;scanf("%d",&q);
while(q--)
{
int p;scanf("%d",&p);
sum=min0(sum,dis[p]);
}
if(sum==max0)printf("-1\n");
else printf("%d\n",sum);
}
return 0;
}