P1629 邮递员送信

题目描述

有一个邮递员要送东西,邮局在节点1.他总共要送N-1样东西,其目的地分别是2~N。由于这个城市的交通比较繁忙,因此所有的道路都是单行的,共有M条道路,通过每条道路需要一定的时间。这个邮递员每次只能带一样东西。求送完这N-1样东西并且最终回到邮局最少需要多少时间。

输入输出格式

输入格式:

第一行包括两个整数N和M。

第2到第M+1行,每行三个数字U、V、W,表示从A到B有一条需要W时间的道路。 满足1<=U,V<=N,1<=W<=10000,输入保证任意两点都能互相到达。

【数据规模】

对于30%的数据,有1≤N≤200;

对于100%的数据,有1≤N≤1000,1≤M≤100000。

输出格式:

输出仅一行,包含一个整数,为最少需要的时间。

输入输出样例

输入样例#1:

5 10
2 3 5
1 5 5
3 5 6
1 2 8
1 3 8
5 3 4
4 1 8
4 5 3
3 5 6
5 4 2

  

输出样例#1:
83

我们看到这个题首先想到的就是Floyd,因为这是有向边,而且邮递员出去之后还要再回来的嘛。

but应该只能拿一部分分,因为范围太大Ο(n^3)跑不动,

那么就另寻他路喽。

(绞尽脑汁终于想了出来)

建两张图,跑两遍dijkstra就能过了,至于为什么,看下面

我们先正常的建图,这个跑出来是到每一个节点的距离然后把这些距离加起来,存到ANS里面,然后反向建一张图,为啥呢?

因为我们反向建一张图再跑的时候从别的点回到起点的边就变成了从起点到别的点,这是我们跑出来的结果就是从每一个节点再回到起点的距离,把这些距离也加到ANS中,到最后输出ANS就可以了

啦啦啦啦啦啦啦 上代码

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>
#define MAXN 100005
#define INF 2147483647 using namespace std; int n, m, cnt;
long long ans;
int u[MAXN], v[MAXN], w[MAXN];
int first[MAXN], next[MAXN];
bool book[MAXN];
int ddd[1005][1005];
int dis[1005];
int uu[MAXN], vv[MAXN], ww[MAXN];
int f[MAXN], nn[MAXN]; int main() {
scanf("%d%d", &n, &m);
for(int i=1; i<=n; i++) {
dis[i] = INF;
}
for(int i=1; i<=n; i++)
for(int j=1; j<=n; j++)
ddd[i][j] = INF;
dis[1] = 0;
memset(f, -1, sizeof(f));
memset(first, -1, sizeof(first));
for(int i=1; i<=m; i++) {
int x, y, z;
scanf("%d%d%d", &x, &y, &z);
ddd[x][y] = min(ddd[x][y], z);
}
for(int i=1; i<=n; i++) {
for(int j=1; j<=n; j++) {
if(ddd[i][j] != INF) {
cnt++;
u[cnt] = i, v[cnt] = j, w[cnt] = ddd[i][j];
next[cnt] = first[u[cnt]];
first[u[cnt]] = cnt;
uu[cnt] = j, vv[cnt] = i, ww[cnt] = ddd[i][j];
nn[cnt] = f[uu[cnt]];
f[uu[cnt]] = cnt;
}
}
}
for(int i=1; i<n; i++) {
int minn = INF, x;
for(int j=1; j<=n; j++) {
if(minn > dis[j]&&book[j] == 0) {
minn = dis[j];
x = j;
}
}
book[x] = 1;
int k = first[x];
while(k != -1) {
if(dis[v[k]] > dis[u[k]]+w[k]) {
dis[v[k]] = dis[u[k]]+w[k];
}
k = next[k];
}
}
for(int i=2; i<=n; i++) {
// if(dis[i] != INF)
ans += dis[i];
}
for(int i=1; i<=n; i++) {
dis[i] = INF;
}
dis[1] = 0;
memset(book, 0, sizeof(book));
for(int i=1; i<n; i++) {
int minn = INF, h;
for(int j=1; j<=n; j++) {
if(minn > dis[j]&&book[j] == 0) {
minn = dis[j];
h = j;
}
}
book[h] = 1;
int k = f[h];
while(k != -1) {
if(dis[vv[k]] > dis[uu[k]]+ww[k]) {
dis[vv[k]] = dis[uu[k]]+ww[k];
}
k = nn[k];
}
}
for(int i=2; i<=n; i++) {
// if(dis[i] != INF)
ans += dis[i];
}
printf("%lld\n",ans);
}

  

Luogu P1629 邮递员送信的更多相关文章

  1. 洛谷——P1629 邮递员送信

    P1629 邮递员送信 题目描述 有一个邮递员要送东西,邮局在节点1.他总共要送N-1样东西,其目的地分别是2~N.由于这个城市的交通比较繁忙,因此所有的道路都是单行的,共有M条道路,通过每条道路需要 ...

  2. 洛谷 P1629 邮递员送信 题解

    P1629 邮递员送信 题目描述 有一个邮递员要送东西,邮局在节点1.他总共要送N-1样东西,其目的地分别是2~N.由于这个城市的交通比较繁忙,因此所有的道路都是单行的,共有M条道路,通过每条道路需要 ...

  3. 洛谷 P1629 邮递员送信-反向建边

    洛谷 P1629 邮递员送信 题目描述: 有一个邮递员要送东西,邮局在节点 11.他总共要送 n-1n−1 样东西,其目的地分别是节点 22 到节点 nn.由于这个城市的交通比较繁忙,因此所有的道路都 ...

  4. 洛谷—— P1629 邮递员送信

    https://www.luogu.org/problem/show?pid=1629 题目描述 有一个邮递员要送东西,邮局在节点1.他总共要送N-1样东西,其目的地分别是2~N.由于这个城市的交通比 ...

  5. 洛谷P1629 邮递员送信 最短路-Djistra

    先上一波题目qwq https://www.luogu.org/problem/P1629· 复习了一波 dijstra 的 priority_queue(优先队列)优化的写法 tips: 求单项路中 ...

  6. 洛谷P1629 邮递员送信

    题目描述 有一个邮递员要送东西,邮局在节点1.他总共要送N-1样东西,其目的地分别是2~N.由于这个城市的交通比较繁忙,因此所有的道路都是单行的,共有M条道路,通过每条道路需要一定的时间.这个邮递员每 ...

  7. P1629 邮递员送信

    题目描述: 有一个邮递员要送东西,邮局在节点1.他总共要送N-1样东西,其目的地分别是2~N.由于这个城市的交通比较繁忙,因此所有的道路都是单行的,共有M条道路,通过每条道路需要一定的时间.这个邮递员 ...

  8. 洛谷 P1629 邮递员送信

    题目描述 有一个邮递员要送东西,邮局在节点1.他总共要送N-1样东西,其目的地分别是2~N.由于这个城市的交通比较繁忙,因此所有的道路都是单行的,共有M条道路,通过每条道路需要一定的时间.这个邮递员每 ...

  9. P1629 邮递员送信(未完成)

    题目描述 有一个邮递员要送东西,邮局在节点1.他总共要送N-1样东西,其目的地分别是2~N.由于这个城市的交通比较繁忙,因此所有的道路都是单行的,共有M条道路,通过每条道路需要一定的时间.这个邮递员每 ...

随机推荐

  1. user agent stylesheet 解决方法

    写了一个写了一个页面字体一直是加粗.原来是 strong,b{ user agent stylesheet font-weight:bold; } 引起的 解决方法:又一次定义 strong,b{ f ...

  2. 初识bigdata时的一些技能小贴士

    既然小豆腐如此给力,而且充分的利用主动学习的优势,已经有了迅速脑补,压倒式的优势,不过这只是表面而已,一切才刚刚开始,究竟鹿死谁手,还有待验证. 以上可以看到,小豆腐为什么拼命的要teach我们了么, ...

  3. mysql20170410练习代码+笔记

    今天的几道高级sql查询真的挺难的,感觉好像视频里讲过,当时也没有练,已经淡化了很多,sql还是要多练习啊!确实逻辑性挺强的. SELECT studentResult,studentNO FROM ...

  4. linux 网络编程-基础篇01

    #Socket简介 是一个编程接口是一种特殊的文件描述符(everything in Unix is a file)并不仅限于TCPIP协议面向连接(Transmission Control Prot ...

  5. atcoder 076

    日本人的比赛 C:如果两个数差了大于1无解,否则分类讨论 #include<bits/stdc++.h> using namespace std; typedef long long ll ...

  6. 40. combo的displayField和valueField属性

    转自:https://xsl2007.iteye.com/blog/773464 下拉框combo可以设置displayField和valueField属性,这两个值值相当于Java中的map,一个键 ...

  7. 使用psutil模块获取电脑运行信息

    psutil是python的一个用于获取cpu信息的模块,非常好使,以下附上官方的一些example: CPU-> Examples >>> import psutil > ...

  8. vue实现全选,反选

    1.example.vue <template> <table class="table-common"> <tr> <th class= ...

  9. An problem about date 根据年月日计算 星期几

    /W = (d+2*m+3*(m+1)/5+y+y/4-y/100+y/400) mod 7(1.2月需要看作上一年的13.14月) #include<stdio.h> #include& ...

  10. 小HY的四元组

    4.7 比赛T1,然而这题爆零了 其实很简单的...其实哈希都不用 所以首先记录每组的差值,按其sort一下再暴力找即可 #include<cstdio> #include<iost ...