今天北邮校赛的一道题,最短路。
一开始的思路是1000个点都做一次SPFA,然后找出到询问值的最短路,但是T到死。
后来想了一下,发现其实可以将1000个点都指向一个超级源点,然后由该点出发开始搜,只需一遍,最后输出结果就可以了。
今天在这题上浪费了太多的时间,发挥的不是很好=。=加油吧。
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <string>
#include <cmath>
#include <cstring>
#include <queue>
#include <set>
#include <vector>
#include <stack>
#include <map>
#include <iomanip>
#define PI acos(-1.0)
#define Max 2005
#define inf 1<<28
#define LL(x) (x<<1)
#define RR(x) (x<<1|1)
#define FOR(i,s,t) for(int i=(s);i<=(t);++i)
#define ll long long
#define mem(a,b) memset(a,b,sizeof(a))
#define mp(a,b) make_pair(a,b)
using namespace std;
int head[10005];
struct kdq
{
int v,val,next;
}edge[1000005 * 2];
int num = 0;
int n , m;
void add(int s,int e,int val)
{
edge[num].v = s;
edge[num].val = val;
edge[num].next = head[e];
head[e] = num ++;
edge[num].v = e;
edge[num].val = val;
edge[num].next = head[s];
head[s] = num ++;
}
int dis[10005];
void init()
{
mem(head,-1);
for (int i = 0 ;i <= n ;i ++)
dis[i] = inf;
num = 0;
}
bool vis[10005];
int qu[10000005];
void spfa(int s)
{
int nn = 1, cn = 0;
qu[0] = s ;
vis[s] = 1;
dis[s] = 0;
while(nn > cn)
{
int temp = qu[cn ++];
vis[temp] = 0;
for (int i = head[temp] ;i != -1 ;i = edge[i].next)
{
int t = edge[i].v;
int tt = edge[i].val;
if(dis[t] > dis[temp] + tt)
{
dis[t] = dis[temp] + tt ;
if(!vis[t])
{
vis[t] = 1;
qu[nn ++] = t;
}
}
}
}
}
int main()
{
int T;
cin >> T;
while ( T -- )
{
cin >> n >> m ;
init();
for (int i = 0 ;i < m ;i ++)
{
int a,b,c;
scanf("%d%d%d",&a,&b,&c);
add(a,b,c);
}
int S ;
cin >> S ;
for(int i = 0 ; i < S ; i ++)//把起点全部和超级源点连起来,就是0.
{
int dd;
scanf("%d",&dd);
add(0,dd,0);
}
int E;
spfa(0);
cin >> E;
while( E -- )
{
int e;
cin >>e;
int ans = dis[e];
if(ans == inf)
ans = -1;
cout <<ans<<endl;
}
cout <<endl;
}
return 0;
}