Time Limit: 1 second

Memory Limit: 128 MB

【问题描述】

在电视时代,没有多少人观看戏剧表演。Malidinesia古董喜剧演员意识到这一事实,他们想宣传剧院,尤其是古色古香的喜剧片。他们已经打印请帖和所有必要的信息和计划。许多学生被雇来分发这些请柬。每个学生志愿者被指定一个确切的公共汽车站,他或她将留在那里一整天,邀请人们参与。   这里的公交系统是非常特殊的:所有的线路都是单向的,连接两个站点。公共汽车离开起始点,到达目的地之后又空车返回起始点。  学生每天早上从总部出发,乘公交车到一个预定的站点邀请乘客。每个站点都被安排了一名学生。在一天结束的时候,所有的学生都回到总部。现在需要知道的是,学生所需的公交费用的总和最小是多少。

【输入格式】

第1行有两个整数n、m(1<=n,m<=1000000),n是站点的个数,m是线路的个数。 然后有m行,每行描述一个线路,包括3个整数,起始点,目的地和价格。 总部在第1个站点,价钱都是整数,且小于1000000000。

【输出格式】

输出一行,表示最小费用。

【数据规模】

Sample Input1

4 6
1 2 10
2 1 60
1 3 20
3 4 10
2 4 5
4 1 50

Sample Output1

210 

【样例说明】

学生各自从总部被派遣到2,3,4站点,然后又回到总部
1-2-4-1:10+5+50=65
1-3-4-1:20+10+50=80
1-2-4-1:10+5+50=65
65+80+65=210
此题数据规模较大,需要使用较为高效的算法,此题不设小规模数据分数。

【题解】

这题的图算是比较的密集的图。如果用spfa的话。第一个点无法通过。而应该用dijkstra+堆优化来实现。

因为后者更擅长解决密集的图的问题。

做法是这样。

一开始输入图的时候,建一个正图和一个反图。

然后分别在正图和反图上做从起点1到其他点的最短路。

然后获取的dis[0][1..n],dis[1][1..n]分别表示在正图和反图上1到其他点的最短路。

最后答案累加dis[0][i]+dis[i](i∈[2..n]);

难点在dijkstra的堆优化(堆操作)

【代码】
#include <cstdio>
#include <cstring> struct data
{
int from;
}; int n, m, first[2][1000001], next[2][1000001] = { 0 }, en[2][1000001], tot[2] = { 0 };
__int64 cost[2][1000001], dis[2][1000001] = { 0 },ans = 0;//0是正图,1是反图 邻接表存储!。
int sizedui,now,nali[1000001],pos;
data dui[1000001];//堆 void up_adjust(int p)//从p开始往上调整堆
{
__int64 x = dis[now][dui[p].from];//先取得这个堆这个位置上的数据 只要记录下标就好。
data temp = dui[p]; //作为temp整个记录dui[p] ->其实等价记录下标。
int i = p, j = p / 2;
while (j > 0)//如果没有超过堆的范围
{
if (x < dis[now][dui[j].from])//如果要调整则调整
{
nali[dui[j].from] = i;//要记录这个下标在堆中的位置
dui[i] = dui[j];//调整
i = j;
j = i / 2;
}
else
break;
}
dui[i] = temp;//把它赋值到新的位置上。
nali[temp.from] = i;//更新它在堆中的位置。
} void down_adjust(int p)//把堆中的数据从p开始往下调整
{
__int64 x = dis[now][dui[p].from];//同样获取这个数据
data temp = dui[p];//先用temp存下来。
int i = p, j = p * 2;
while (j <= sizedui)//如果没有超过堆的范围。
{
if (j < sizedui && dis[now][dui[j + 1].from] < dis[now][dui[j].from])//如果j+1指向数据更小
j++;//则递增j
if (x > dis[now][dui[j].from])//如果需要调整
{
nali[dui[j].from] = i;//改变j在堆中的位置,在外面要用一个数组记录。
dui[i] = dui[j];//调整
i = j;
j = i * 2;
}
else
break;
}
dui[i] = temp;//调整到新的位置(如果要)
nali[temp.from] = i;//改变它在nali数组中记录的位置。
} void dijkstra(int fx) //fx == 0 表示正方向 fx==1表示反方向。
{
memset(nali, 0, sizeof(nali));//nali数组要初始化。
memset(dis[fx], 255, sizeof(dis[fx]));//fx一开始赋值为-1,表示正无穷
now = fx; //这是用于向上调整过程和向下调整过程中记录当前图的方向。
sizedui = 1;//堆的大小。
dis[fx][1] = 0;//初始化dis[0] == 0;
dui[sizedui].from = 1;//在堆中的数据
nali[1] = 1;//一开始在1位置
bool bo[1000001];//判断某个点是否已经找到最短距离
memset(bo, false, sizeof(bo));//初始化都没找到最短距离
for (int i = 1; i <= n; i++)
{
if (sizedui == 0) //如果堆中已经不存在数据了。则结束程序、表示都找到了。
break;
int k = dui[1].from;//取出堆顶的最小的元素。
nali[k] = 0;//把k在堆中的位置置为0
dui[1] = dui[sizedui];//把堆底的元素放到堆顶。
sizedui--;
down_adjust(1);//从堆底往下调整。
bo[k] = true;//表示k已经找到了最短路
int temp = first[fx][k];//找k元素的出度
while (temp != 0)
{
int y = en[fx][temp];//获取其一个出度
__int64 w = cost[fx][temp];//获取这条路径的花费。
if (!bo[y] && (dis[fx][y] == -1 || dis[fx][y] > dis[fx][k] + w))
{//如果该出度未找到最短路 且其为无穷大或能够更新dis值。
dis[fx][y] = dis[fx][k] + w;//更新dis值
if (nali[y] != 0)//如果它已经在堆中了
{
up_adjust(nali[y]);//就尝试先往上调整(因为会变大,所以实则只需往下调整);
down_adjust(nali[y]);//再尝试往下调整
}
else
{
sizedui++;
dui[sizedui].from = y;//如果不在堆中。就把它加到堆的堆底。
nali[y] = sizedui;//更新其在堆中的位置.
up_adjust(sizedui);//先往上调整。
down_adjust(nali[y]);//再往下调整。
}
}
temp = next[fx][temp];//找下一个出度
}
}
} int main()
{
scanf("%d%d", &n, &m);
for (int i = 1; i <= m; i++)//用邻接表来存正图和反图
{
int x, y, z;
scanf("%d%d%d", &x, &y, &z);
tot[0]++;//链式存储存正图
next[0][tot[0]] = first[0][x];
first[0][x] = tot[0];
en[0][tot[0]] = y;
cost[0][tot[0]] = z; tot[1]++;//链式存储存反图。
next[1][tot[1]] = first[1][y];
first[1][y] = tot[1];
en[1][tot[1]] = x;
cost[1][tot[1]] = z;
} dijkstra(0);//在正图和反图上做最短路
dijkstra(1); for (int i = 2; i <= n; i++)//最后输出到达和返回的最短路的和即可。
ans += (dis[0][i] + dis[1][i]);
printf("%I64d\n", ans);
return 0;
}

【u017】请柬的更多相关文章

  1. [Luogu1342] 请柬 - 最短路模板

    Description 在电视时代,没有多少人观看戏剧表演.Malidinesia古董喜剧演员意识到这一事实,他们想宣传剧院,尤其是古色古香的喜剧片.他们已经打印请帖和所有必要的信息和计划.许多学生被 ...

  2. P1342 请柬

    最近一直在做最短路......所以今天就再做一道最短路吧.... 题目描述 在电视时代,没有多少人观看戏剧表演.Malidinesia古董喜剧演员意识到这一事实,他们想宣传剧院,尤其是古色古香的喜剧片 ...

  3. 洛谷P1342 请柬(SPFA)

    To 洛谷.1342 请柬 题目描述 在电视时代,没有多少人观看戏剧表演.Malidinesia古董喜剧演员意识到这一事实,他们想宣传剧院,尤其是古色古香的喜剧片.他们已经打印请帖和所有必要的信息和计 ...

  4. 洛谷 P1342 请柬(SPFA)

    题目描述 在电视时代,没有多少人观看戏剧表演.Malidinesia古董喜剧演员意识到这一事实,他们想宣传剧院,尤其是古色古香的喜剧片.他们已经打印请帖和所有必要的信息和计划.许多学生被雇来分发这些请 ...

  5. 基于jquery结婚电子请柬特效素材

    分享基于jquery结婚电子请柬特效素材总共包含3个部分,第一部分是开着小轿车缓缓进入场景,第二部分是相册,第三部分是祝福墙.效果图如下: 在线预览   源码下载 实现的代码. html代码: < ...

  6. 洛谷P1342 请柬

    P1342 请柬 题目描述 在电视时代,没有多少人观看戏剧表演.Malidinesia古董喜剧演员意识到这一事实,他们想宣传剧院,尤其是古色古香的喜剧片.他们已经打印请帖和所有必要的信息和计划.许多学 ...

  7. 洛谷 P1342 请柬

    题目描述 在电视时代,没有多少人观看戏剧表演.Malidinesia古董喜剧演员意识到这一事实,他们想宣传剧院,尤其是古色古香的喜剧片.他们已经打印请帖和所有必要的信息和计划.许多学生被雇来分发这些请 ...

  8. 洛谷—— P1342 请柬

    https://www.luogu.org/problemnew/show/1342 题目描述 在电视时代,没有多少人观看戏剧表演.Malidinesia古董喜剧演员意识到这一事实,他们想宣传剧院,尤 ...

  9. luogu P1342 请柬

    题目描述 在电视时代,没有多少人观看戏剧表演.Malidinesia古董喜剧演员意识到这一事实,他们想宣传剧院,尤其是古色古香的喜剧片.他们已经打印请帖和所有必要的信息和计划.许多学生被雇来分发这些请 ...

随机推荐

  1. 【2017 Multi-University Training Contest - Team 6】Inversion

    [链接]h在这里写链接 [题意] 给出一个序列,求2~n每一个数,下标不是这个数倍数的最大值是什么? [题解] 把a数组从大到小排序. 每个位置i,逆序枚举b数组,找到第一个对应下标不是i的倍数的,直 ...

  2. Jquery获取select选中的option的文本信息

    注意:以下用的$(this)代表当前选中的select框 第一种: $(this).children("option:selec... ...查看全文

  3. C++ 学习路线推荐

        相信有非常大一部分学计算机的童鞋都是靠自学,即使本身是计算机专业的同学,也会认为只通过课堂上的学习是远远不够的,并且在上课时所用到的教材也不够好.然而自学的时候有个非常大的问题就是找不到合适的 ...

  4. Warning: Division by zero in 错误处理

    Warning: Division by zero in 错误处理 今天调试一段代码,结果提示 Warning: Division by zero in ,没有扫到答案,最后发现 $dir/$name ...

  5. Android实现点击通知栏后,先启动应用再打开目标Activity

    情况简述 在开发Android app的过程中,遇到这样一个需求:app中启动一个Service,该Service在独立进程中运行,与服务器保持长连接,将服务器推送过来的消息在通知栏中显示,并设置点击 ...

  6. [置顶] WebService学习总结(4)——第三方webService服务调用

    互联网上面有很多的免费webService服务,我们可以调用这些免费的WebService服务,将一些其他网站的内容信息集成到我们的Web应用中显示,下面就以获取天气预报数据和查询国内手机号码归属地为 ...

  7. 洛谷 P2118 比例简化

    P2118 比例简化 题目描述 在社交媒体上,经常会看到针对某一个观点同意与否的民意调查以及结果.例如,对某一观点表示支持的有1498 人,反对的有 902人,那么赞同与反对的比例可以简单的记为149 ...

  8. Altium Designer 在pcb下导入的原件引脚是绿的

    当然也可能是其他规则原因导致的

  9. CSS笔记 - fgm练习 - 三个div变色 - CSS div等分布局

    <title>三个div变红</title> <style> *{margin: 0; padding: 0} body{ text-align: center; ...

  10. IR_drop

    IR压降是指出现在集成电路中电源和地网络上电压下降或升高的一种现象.随着半导体工艺的演进金属互连线的宽度越来越窄,导致它的电阻值上升,所以在整个芯片范围内将存在一定的IR压降.IR压降的大小决定于从电 ...