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 } 
View Code

 

posted @ 2018-09-23 07:11  cellur925&Chemist  阅读(190)  评论(0编辑  收藏  举报