题目大意:
起点为1号点,求1到所有点最短路径及所有点到1的最短路径来回总和
思路:
因为题目规模太大,不能用二维数组来存储点与点之间的权值,而且考虑到也会超时,所以选用spfa加邻接表的方式来做这道题
1-所有其他点的最短路径很好求,而其他点到1的的最短距离可以通过把起点与终点反向从而求出的便是其他点到1的距离了
代码如下:
#include <iostream> #include<queue> #include<cstring> #include<cstdio> using namespace std; const int maxs = 1000000+5; const __int64 INF = 0xFFFFFFFF; __int64 dist1[maxs],dist2[maxs],ans=0; struct Edge { int e,next,weight; }edge1[maxs],edge2[maxs]; int head1[maxs],head2[maxs]; int n,m; void spfa(Edge edge[],__int64 dist[],int head[maxs]) { bool vis[maxs]; memset(vis,false,sizeof(vis)); for(int i=1;i<=n;i++) dist[i]=INF; dist[1]=0; queue<int> q; q.push(1); vis[1]=true; while(!q.empty()) { int cur = q.front(); q.pop(); vis[cur]=false; for(int i=head[cur];i!=-1;i=edge[i].next) { if(dist[edge[i].e]>dist[cur]+edge[i].weight) { dist[edge[i].e]=dist[cur]+edge[i].weight; if(!vis[edge[i].e]) { q.push(edge[i].e); vis[edge[i].e]=true; } } } } } int main() { freopen("in.txt","r",stdin); int T; scanf("%d",&T); while(T--) { scanf("%d%d",&n,&m); memset(head1,-1,sizeof(head1)); memset(head2,-1,sizeof(head2)); memset(edge1,0,sizeof(edge1)); memset(edge2,0,sizeof(edge2)); for(int i=1;i<=m;i++) { int a,b,w; scanf("%d%d%d",&a,&b,&w); edge1[i].e=b; edge1[i].weight=w; edge1[i].next=head1[a]; head1[a]=i; edge2[i].e=a; edge2[i].weight=w; edge2[i].next=head2[b]; head2[b]=i; } ans=0; spfa(edge1,dist1,head1); spfa(edge2,dist2,head2); for(int i=1;i<=n;i++) ans+=(dist1[i]+dist2[i]); printf("%I64d\n",ans); } return 0; }
时间: 2024-10-10 02:57:15