标签:style blog color os io for div log sp
此题中起点有1000个,别有20000条。用链式前向星建图,再枚举起点用SPFA的话,超时了。(按理说,两千万的复杂度应该没超吧。不过一般说计算机计算速度 1~10 千万次/秒。也许拿最烂的计算机来卡时间)
有一个技巧,加一个超级源点。也就是加一个点,使得该点连通所有的起点,并且边的权值为0。这个技巧应用蛮多的。网络流、最小树形图都有题目这样做。
#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 最短路(多源转单源)
标签:style blog color os io for div log sp
原文地址:http://www.cnblogs.com/Potato-lover/p/3948401.html