There are 1000 starting points in this question, not 20000. Creating a graph with a chained forward direction and enumerating the start point using spfa times out. (It is reasonable to say that 20 million of the complexity should not exceed. However, generally speaking, the computing speed of a computer is 1 ~ 10 million times/second. Maybe take the worst computer to take the time)
There is a skill to add a super source point. That is, add a vertex to connect all the starting points and the edge weight is 0. This technique is widely used. Network streams and the shortest tree have questions.
#include<iostream>#include<cstdio>#include<cstring>#include<queue>#include<algorithm>using namespace std;const int N = 1010, M=20010;const int INF = 0x3f3f3f3f;struct node{ int to, w, next;};node edge[M];int head[N], dist[N], outq[N];bool vis[N];int tot;bool SPFA(int s, int n ){ int i,k; for(i=0;i<=n;i++) dist[i]=INF; memset(vis,0,sizeof(vis)); memset(outq,0,sizeof(outq)); queue<int > q; while(!q.empty()) q.pop(); vis[s]=1; dist[s]=0; q.push(s); while(!q.empty()) { int u=q.front(); q.pop(); vis[u]=0; outq[u]++; if(outq[u]>n) return 0 ; k=head[u]; while(k>=0) { if(dist[edge[k].to]-edge[k].w>dist[u]) { dist[edge[k].to]=dist[u]+edge[k].w; if(!vis[edge[k].to]) { vis[edge[k].to]=1; q.push(edge[k].to); } } k=edge[k].next; } } return 1;}void addedge(int i,int j,int w){ edge[tot].to=j; edge[tot].w=w; edge[tot].next=head[i]; head[i]=tot++;}void init(){ tot=0; memset(head,-1,sizeof(head));}int main(){ //freopen("test.txt","r",stdin); int i,j,k,n,m,t,s; while(scanf("%d%d%d",&n,&m,&t)!=EOF) { init(); while(m--) { scanf("%d%d%d",&i,&j,&k); addedge(i,j,k); } scanf("%d",&k); for(i=0;i<k;i++) { scanf("%d",&s); addedge(n+1,s,0); } SPFA(n+1,n+1); if(dist[t]==INF) printf("-1\n"); else printf("%d\n",dist[t]); } return 0;}
Hdu2680 choose the best route (multi-source to single source)