题意 n个点m条单向边 计算 从1到每一个点的权值(除了1) 和每个点回到1 的权值之和
正向跑一次 反向跑一次即可
#include<bits/stdc++.h> using namespace std; //input by bxd #define rep(i,a,b) for(int i=(a);i<=(b);i++) #define repp(i,a,b) for(int i=(a);i>=(b);--i) #define RI(n) scanf("%d",&(n)) #define RII(n,m) scanf("%d%d",&n,&m) #define RIII(n,m,k) scanf("%d%d%d",&n,&m,&k) #define RS(s) scanf("%s",s); #define ll long long #define pb push_back #define REP(i,N) for(int i=0;i<(N);i++) #define CLR(A,v) memset(A,v,sizeof A) #define inf 0x3f3f3f3f ////////////////////////////////////// const int N = 10000000; int pos=0; struct node { int nex,to,v; }edge[N]; int head[N],n; void add(int a,int b,int v) { edge[++pos].nex=head[a]; head[a]=pos; edge[pos].to=b; edge[pos].v=v; } int dis[N],vis[N]; void spfa(int s) { rep(i,1,n) dis[i]=inf,vis[i]=0; dis[s]=0; vis[s]=1; queue<int>q; q.push(s); while(!q.empty()) { int u=q.front();q.pop(); vis[u]=0; for(int i=head[u];i;i=edge[i].nex) { int v=edge[i].to; if(dis[v]>dis[u]+edge[i].v) { dis[v]=dis[u]+edge[i].v; if(!vis[v]) vis[v]=1,q.push(v); } } } } int temp[N][3]; int main() { int cas; RI(cas); while(cas--) { int m; pos=0; CLR(head,0); RII(n,m); rep(i,1,m) { int a,b,c; RIII(a,b,c); add(a,b,c); temp[i][0]=a; temp[i][1]=b; temp[i][2]=c; } spfa(1); int ans=0; rep(i,1,n) ans+=dis[i]; CLR(head,0); pos=0; rep(i,1,m) { add(temp[i][1],temp[i][0],temp[i][2]); } spfa(1); rep(i,1,n) ans+=dis[i]; cout<<ans<<endl; } return 0; }