有趣的最短路结论
P1629 邮递员送信
结论:
对于有向图,在反图中的从 1 出发到其他点的最短路就是在原图中从其他点出发到达 1 的最短路!!
AC码:
#include<bits/stdc++.h> //typedef long long ll; #define rd read() #define int long long #define pos(i,a,b) for(int i=(a);i<=(b);i++) #define neg(i,a,b) for(int i=(a);i>=(b);i--) const int Max=100010; const int inf=0x7f7f7f7f; const int Mod=1e9+7; using namespace std; int n,m,s,d,cnt=0,t; int diis[2*Max]; bool vis[2*Max]; int x[Max],y[Max]; inline int read() { int x=0,k=1; char c=getchar(); while(c<'0'||c>'9'){if(c=='-')k=-1;c=getchar();} while(c>='0'&&c<='9')x=(x<<3)+(x<<1)+(c^48),c=getchar(); return x*k; } struct edge { int to,l,next; }Edge[2*Max]; int head[2*Max]; struct node { int dis,id; bool operator <(const node &x)const { return x.dis<dis; } }; priority_queue<node> q; void add_edge(int v,int u,int d) { Edge[++cnt].next=head[v]; Edge[cnt].to=u; Edge[cnt].l=d; head[v]=cnt; } void dijkstra() { pos(i,1,n*2) diis[i]=inf; diis[s]=0; q.push((node){0,s}); memset(vis,0,sizeof(vis)); while(!q.empty()) { node now=q.top(); q.pop(); int diss=now.dis,idd=now.id; if(vis[idd]) continue; vis[idd]=1; for(int i=head[idd];i;i=Edge[i].next) { int too=Edge[i].to; if(diis[idd]+Edge[i].l<diis[too]) { diis[too]=diis[idd]+Edge[i].l; if(!vis[too]) { q.push((node){diis[too],too}); } } } } } signed main() { while(cin>>n>>m) { cnt=0; pos(i,1,m) { int v=rd,u=rd,w=rd; add_edge(v,u,w); add_edge(u+n,v+n,w); } int ans=0; s=1; dijkstra(); pos(i,1,n) ans+=diis[i]; s=n+1; dijkstra(); pos(i,1+n,n*2) ans+=diis[i]; printf("%lld\n",ans); } return 0; }