是该好好巩固一下QAQ
刷水题使我快乐
论两信竞学生如何讨论一道黄题纠结半个小时
正反各跑一遍spfa 用1次SPFA找各个点到点1的最短路,然后开一个反向图,再用SPFA搜一下点1到反向图各个点的最短路,反向图中点1到各个点的最短路就是普通图中各个点到点1的最短路
1 #include<bits/stdc++.h> 2 using namespace std; 3 const int N=1000+5,inf=1e9; 4 int n,m,ans=0; 5 inline int rd() 6 { 7 int x=0,w=0;char ch=0; 8 while(!isdigit(ch)) w|=ch=='-',ch=getchar(); 9 while(isdigit(ch)) x=(x<<1)+(x<<3)+(ch^48),ch=getchar(); 10 return w?-x:x; 11 } 12 int head[N],head1[N],cnt=0,cnt1=0; 13 struct edge 14 { 15 int v,nxt,w; 16 }e[N*100],e1[N*100]; 17 void add(int u,int v,int w) 18 { 19 e[++cnt].v=v; 20 e[cnt].w=w; 21 e[cnt].nxt=head[u]; 22 head[u]=cnt; 23 } 24 void add1(int u,int v,int w) 25 { 26 e1[++cnt1].v=v; 27 e1[cnt1].w=w; 28 e1[cnt1].nxt=head1[u]; 29 head1[u]=cnt1; 30 } 31 32 int vis[N],dis[N],dis1[N]; 33 void spfa() 34 { 35 memset(vis,0,sizeof(vis)); 36 for(int i=0;i<=n;i++) dis[i]=inf; 37 deque<int> q; 38 q.push_back(1); 39 vis[1]=1,dis[1]=0; 40 while(!q.empty()) 41 { 42 int u=q.front(); 43 q.pop_front();vis[u]=0; 44 for(int i=head[u];i;i=e[i].nxt) 45 { 46 int v=e[i].v,w=e[i].w; 47 if(dis[v]>dis[u]+w) 48 { 49 dis[v]=dis[u]+w; 50 if(!vis[v]) 51 { 52 if(!q.empty()&&dis[v]<=dis[q.front()]) q.push_front(v); 53 else q.push_back(v); 54 vis[v]=1; 55 } 56 } 57 } 58 } 59 } 60 void spfa1() 61 { 62 memset(vis,0,sizeof(vis)); 63 for(int i=0;i<=n;i++) dis1[i]=inf; 64 deque<int> q1; 65 q1.push_back(1); 66 vis[1]=1,dis1[1]=0; 67 while(!q1.empty()) 68 { 69 int u=q1.front(); 70 q1.pop_front();vis[u]=0; 71 for(int i=head1[u];i;i=e1[i].nxt) 72 { 73 int v=e1[i].v,w=e1[i].w; 74 if(dis1[v]>dis1[u]+w) 75 { 76 dis1[v]=dis1[u]+w; 77 if(!vis[v]) 78 { 79 if(!q1.empty()&&dis1[v]<=dis1[q1.front()]) 80 q1.push_front(v); 81 else 82 q1.push_back(v); 83 vis[v]=1; 84 } 85 } 86 } 87 } 88 } 89 90 int main() 91 { 92 memset(head,0,sizeof(head)); 93 memset(head1,0,sizeof(head1)); 94 n=rd(),m=rd(); 95 for(int i=1;i<=m;i++) 96 { 97 int u=rd(),v=rd(),w=rd(); 98 add(u,v,w);add1(v,u,w); 99 } 100 spfa();spfa1(); 101 for(int i=1;i<=n;i++) 102 ans+=dis[i]+dis1[i]; 103 printf("%d",ans); 104 }