题目链接:http://poj.org/problem?id=1511
思路:题目意思很简单就是要求源点到各点的最短路之和,然后再求各点到源点的最短路之和,其实就是建两个图就ok了,其中一个建反图。1000000个点和1000000条边,一开始用SPFA+vector怎么都是TLE,然后换成邻接表就过了=.=。
1 #include<iostream> 2 #include<cstdio> 3 #include<cstring> 4 #include<cmath> 5 #include<vector> 6 #include<queue> 7 using namespace std; 8 #define MAXN 1000100 9 #define inf 1LL<<60 10 11 struct Edge{ 12 int v,w,next; 13 }edge1[MAXN*10],edge2[MAXN*10]; 14 15 int head1[MAXN],head2[MAXN]; 16 long long dist[MAXN]; 17 bool mark[MAXN]; 18 int n,m,NE; 19 20 void Insert(Edge *edge,int *head,int u,int v,int w) 21 { 22 edge[NE].v=v; 23 edge[NE].w=w; 24 edge[NE].next=head[u]; 25 head[u]=NE; 26 } 27 28 29 long long SPFA(Edge *edge,int *head,int u) 30 { 31 memset(mark,false,(n+2)*sizeof(bool)); 32 for(int i=1;i<=n;i++)dist[i]=inf; 33 dist[u]=0; 34 queue<int>Q; 35 Q.push(u); 36 while(!Q.empty()){ 37 u=Q.front(); 38 Q.pop(); 39 mark[u]=false; 40 for(int i=head[u];i!=-1;i=edge[i].next){ 41 int v=edge[i].v,w=edge[i].w; 42 if(dist[u]+w<dist[v]){ 43 dist[v]=dist[u]+w; 44 if(!mark[v]){ mark[v]=true;Q.push(v); } 45 } 46 } 47 } 48 long long ans=0; 49 for(int i=2;i<=n;i++)ans+=dist[i]; 50 return ans; 51 } 52 53 int main() 54 { 55 int _case,u,v,w; 56 scanf("%d",&_case); 57 while(_case--){ 58 scanf("%d%d",&n,&m); 59 NE=0; 60 memset(head1,-1,(n+2)*sizeof(int)); 61 memset(head2,-1,(n+2)*sizeof(int)); 62 while(m--){ 63 scanf("%d%d%d",&u,&v,&w); 64 Insert(edge1,head1,u,v,w); 65 Insert(edge2,head2,v,u,w);//建反图 66 NE++; 67 } 68 printf("%lld\n",SPFA(edge1,head1,1)+SPFA(edge2,head2,1)); 69 } 70 return 0; 71 } 72 73 74 75