LuoguP1342请柬 【最短路/建反图】By cellur925
开始就想直接正向跑一遍Dij把到各点的最短路加起来即可,后来发现与样例少了些,于是再读题发现需要也求出学生们回来的最短路。
但是注意到本题是有向图,如果是无向图就好说。
那么我们怎么解决?可以建一个反图。于是本题就解决了==
Code
1 #include<cstdio> 2 #include<algorithm> 3 #include<cstring> 4 #include<queue> 5 #define maxn 2000090 6 7 using namespace std; 8 typedef long long ll; 9 10 int n,m,tot; 11 int head[maxn],vis[maxn],hea[maxn]; 12 ll ans,dis[maxn],d[maxn]; 13 struct node{ 14 int to,next; 15 int val; 16 }edge[maxn],edg[maxn]; 17 18 void add(int x,int y,int z) 19 { 20 edge[++tot].to=y; 21 edge[tot].next=head[x]; 22 head[x]=tot; 23 edge[tot].val=z; 24 } 25 26 void add_nega(int x,int y,int z) 27 { 28 edg[++tot].to=y; 29 edg[tot].next=hea[x]; 30 hea[x]=tot; 31 edg[tot].val=z; 32 } 33 34 void dijkstra() 35 { 36 priority_queue<pair<int,int> >q; 37 memset(dis,127,sizeof(dis)); 38 q.push(make_pair(0,1));dis[1]=0; 39 while(!q.empty()) 40 { 41 int u=q.top().second;q.pop(); 42 if(vis[u]) continue; 43 vis[u]=1; 44 for(int i=head[u];i;i=edge[i].next) 45 { 46 int v=edge[i].to; 47 if(dis[v]>dis[u]+edge[i].val) 48 { 49 dis[v]=dis[u]+edge[i].val; 50 if(!vis[v]) q.push(make_pair(-dis[v],v)); 51 } 52 } 53 } 54 } 55 56 void dijk() 57 { 58 priority_queue<pair<int,int> >q; 59 memset(d,127,sizeof(d)); 60 memset(vis,0,sizeof(vis)); 61 q.push(make_pair(0,1));d[1]=0; 62 while(!q.empty()) 63 { 64 int u=q.top().second;q.pop(); 65 if(vis[u]) continue; 66 vis[u]=1; 67 for(int i=hea[u];i;i=edg[i].next) 68 { 69 int v=edg[i].to; 70 if(d[v]>d[u]+edg[i].val) 71 { 72 d[v]=d[u]+edg[i].val; 73 if(!vis[v]) q.push(make_pair(-d[v],v)); 74 } 75 } 76 } 77 } 78 79 int main() 80 { 81 scanf("%d%d",&n,&m); 82 for(int i=1;i<=m;i++) 83 { 84 int x=0,y=0,z=0; 85 scanf("%d%d%d",&x,&y,&z); 86 add(x,y,z);add_nega(y,x,z); 87 } 88 dijkstra(); 89 dijk(); 90 for(int i=1;i<=n;i++) 91 ans+=dis[i]+d[i]/*,printf("%d\n",dis[i])*/; 92 printf("%lld",ans); 93 return 0; 94 }
独立意志与自由思想是必须争的,且须以生死力争。