题目链接:
题意:
给出一个M个点N条边的单向图 1 <= M,N <= 1000000. 给出每条边的两端和经过所需要的时间,求从第一点分别到达所有其他点(2~M)再回到第一点的最短时间
题解:
1 <= M,N <= 1000000. 邻接矩阵肯定会爆内存 所以spfa邻接表解决即可 注意好反向边的建立
代码:
#include<iostream> #include<cstdio> #include<cstring> #include<queue> #define maxx 0x3f3f3f3f using namespace std; struct node { int to,w; int pre; } edge[1000005][2]; int dis[1000005]; int vis[1000005]; int next[1000005][2]; int m,s1,s2,start,endd; void addedge() { int u,v,weight; scanf("%d%d%d",&u,&v,&weight); edge[s1][0].to=v; edge[s1][0].w=weight; edge[s1][0].pre=next[u][0]; next[u][0]=s1++; edge[s2][1].to=u; edge[s2][1].w=weight; edge[s2][1].pre=next[v][1]; next[v][1]=s2++; return; } void spfa(int d) { for(int j=0; j<=m; j++) { vis[j]=0; dis[j]=maxx; } queue<int>q; int head; dis[1]=0; q.push(1); while(!q.empty()) { head=q.front(); q.pop(); vis[head]=0; for(int i=next[head][d]; i!=-1; i=edge[i][d].pre) { if(dis[head]+edge[i][d].w<dis[edge[i][d].to]) { dis[edge[i][d].to]=dis[head]+edge[i][d].w; if(!vis[edge[i][d].to]) { vis[edge[i][d].to]=1; q.push(edge[i][d].to); } } } } return; } int main() { int t,n,i,j; __int64 ans; scanf("%d",&t); while(t--) { s1=s2=0; ans=0; scanf("%d%d",&m,&n); for(i=0; i<=m; i++) next[i][0]=next[i][1]=-1; while(n--) { addedge(); } spfa(0); for(i=2; i<=m; i++) ans=ans+dis[i]; spfa(1); for(i=2; i<=m; i++) ans=ans+dis[i]; printf("%I64d\n",ans); } return 0; }
时间: 2024-10-16 04:11:36