P1629 邮递员送信

题目链接 https://www.luogu.com.cn/problem/P1629

好嘛,又没看清题,我以为只需要让dis*2就好了呢,结果就听取WA声一片了呗。

结果仔细看题目才发现这是个有向图,不是走到终点接着回头这么简单的。


 

既然这样,邮递员在回来的时候就是求多源点到单源点最短路的情况了,啊这,总不能n个单源到单源吧?!

(废话这范围当然不行)

反向建边:建图时将边的方向都相反,那么反向图中A点(源点)到B点(任意一点)的最短路径,就是正向图中B点(任意一点)到A点(源点)的最短路径。

画个图就明白了。


 

(代码写得有点儿啰嗦了,其实不用两个函数)

放AC代码

  1 #include<bits/stdc++.h>
  2 using namespace std;
  3 int n,m;
  4 int cnt;
  5 int ans;
  6 bool vis[1010],fvis[1010];
  7 int head[1010],fhead[1010];
  8 long long dis[1010],fdis[1010];
  9 
 10 struct Edge
 11 {
 12     int v;
 13     int w;
 14     int next;
 15 } edge[100010],fedge[100010];
 16 
 17 void add(int a,int b,int c)
 18 {
 19     edge[++cnt].v=b;
 20     edge[cnt].w=c;
 21     edge[cnt].next=head[a];
 22     head[a]=cnt;
 23     fedge[cnt].v=a;
 24     fedge[cnt].w=c;
 25     fedge[cnt].next=fhead[b];
 26     fhead[b]=cnt;
 27 }
 28 
 29 void dijkstra()
 30 {
 31     for(int v=1; v<=n; v++)
 32         dis[v]=INT_MAX;
 33 
 34     int cur=1;
 35     dis[cur]=0;
 36     long long minn;
 37 
 38     while(!vis[cur])
 39     {
 40         vis[cur]=true;
 41         for(int i=head[cur]; i!=0; i=edge[i].next)
 42         {
 43             if(!vis[edge[i].v] && dis[cur]+edge[i].w<dis[edge[i].v])
 44                 dis[edge[i].v]=dis[cur]+edge[i].w;
 45         }
 46         minn=INT_MAX;
 47         for(int i=1;i<=n;i++)
 48         {
 49             if(!vis[i] && dis[i]<minn)
 50             {
 51                 minn=dis[i];
 52                 cur=i;
 53             }
 54         }
 55     }
 56 }
 57 
 58 void fdijkstra()
 59 {
 60     for(int v=1; v<=n; v++)
 61         fdis[v]=INT_MAX;
 62 
 63     int cur=1;
 64     fdis[cur]=0;
 65     long long minn;
 66 
 67     while(!fvis[cur])
 68     {
 69         fvis[cur]=true;
 70         for(int i=fhead[cur]; i!=0; i=fedge[i].next)
 71         {
 72             if(!fvis[fedge[i].v] && fdis[cur]+fedge[i].w<fdis[fedge[i].v])
 73                 fdis[fedge[i].v]=fdis[cur]+fedge[i].w;
 74         }
 75         minn=INT_MAX;
 76         for(int i=1;i<=n;i++)
 77         {
 78             if(!fvis[i] && fdis[i]<minn)
 79             {
 80                 minn=fdis[i];
 81                 cur=i;
 82             }
 83         }
 84     }
 85 }
 86 
 87 int main()
 88 {
 89     cin>>n>>m;
 90     for(int e=1; e<=m; e++)
 91     {
 92         int a,b,c;
 93         cin>>a>>b>>c;
 94         add(a,b,c);
 95     }
 96     dijkstra();
 97     fdijkstra();
 98     for(int i=1;i<=n;i++)
 99         ans+=dis[i]+fdis[i];
100     cout<<ans;
101     return 0;
102 }

 

posted @ 2022-04-26 21:36  爱吃虾滑  阅读(19)  评论(0编辑  收藏  举报