题目大意:求一个从地点然后再从一个地点返回过来,的最短路径.
思路:正向+逆向建图
#include<iostream> #include<cstring> #include<queue> #include<cstdio> #define inf 0x3f3f3f3f using namespace std; bool vis[1000010]; int n,head1[1000010],s1,head2[1000010],s2,ans,dis[1000010],dis2[1000010]; struct node { int to,w,next; }q1[1000010],q2[1000010]; void add1(int a,int b,int c) { q1[s1].to=b; q1[s1].w=c; q1[s1].next=head1[a]; head1[a]=s1++; } void add2(int a,int b,int c) { q2[s2].to=a; q2[s2].w=c; q2[s2].next=head2[b]; head2[b]=s2++; } void SPFA1(int st) { int k; queue<int>Q; for(int i=1;i<=n;i++) dis[i]=inf; memset(vis,false,sizeof(vis)); dis[st]=0; vis[st]=true; Q.push(st); while(!Q.empty()) { k=Q.front(); Q.pop(); vis[k]=false; for(int i=head1[k];i!=-1;i=q1[i].next) { int v=q1[i].to; if(dis[v]>dis[k]+q1[i].w) { dis[v]=dis[k]+q1[i].w; if(!vis[v]) { vis[v]=true; Q.push(v); } } } } } void SPFA2(int st) { queue<int >Q; int i,j,k; memset(vis,false,sizeof(vis)); for(i=1;i<=n;i++) { dis2[i]=inf; } dis2[st]=0; vis[st]=true; Q.push(st); while(!Q.empty()) { k=Q.front(); Q.pop(); vis[k]=false; for(i=head2[k];i!=-1;i=q2[i].next) { int u=q2[i].to; if(dis2[u]>dis2[k ]+q2[i].w) { dis2[u]=dis2[k]+q2[i].w; if(!vis[u]) { vis[u]=true; Q.push(u); } } } } } int main() { int m,i,j,t,a,b,c; int cla; scanf("%d",&cla); while(cla--) { ans=0; s2=s1=1; memset(head1,-1,sizeof(head1)); memset(head2,-1,sizeof(head2)); scanf("%d%d",&n,&m); for(i=0;i<m;i++) { scanf("%d%d%d",&a,&b,&c); add1(a,b,c); add2(a,b,c); } SPFA1(1); SPFA2(1); for(i=1;i<=n;i++) { ans+=dis[i]+dis2[i]; } printf("%d\n",ans); } return 0; }