题意

给定一个图,要我们从1号点出发,经过一系列点后重新回到1点,求出最短距离是多少,限制是每条边只能通过一次。

分析

对于这种求最短路径的题,我们一开始当然是想到SPFA,DIJ等一些列的求最短路算法了啦。
但是怎么处理那些限制条件呢,能解决这个问题,就可以切了这题了。
首先,我们可以先把原图构建出来,跑一遍SPFA
求出每个点到1的最短距离dis[i],并设Pre[i]表示这条路径上与1相连的点的标号。
这样我们就可以通过这个Pre推测出一条边是否被使用过。
Pre表示,直接与1相连的点的值为其本身,其他的点的值等于其前驱结点的Pre值
得到这些后就可以构建新图了。

我们可以很清楚地知道,由于题目要求最后必须回到1号点,所以我们最好把1号点拆开成两个点,把新拆出的点记为n+1号点,,然后我们要把原图改一改(也就是建新图了).让我们枚举每条边,然后进行下列操作,

part 1:该边为x连向1,边权为value。

(1)当pre[x]!=x说明从1到x的最短路并没有经过这条边,所以这条边的可以被使用的,那么让我们在新图中建立一条从起点1到终点n+1的边,边权为value+dis[x]
(2)当pre[x]==x说明从1到x的最短路是使用了这条边的,所以在新图中建立该边的时候,边的权值不可以带上dis[x],那么让我们在新图中建立从x到终点n+1的边,边权为value.

Part2:该边为从1连向x,边权为value

(1)当pre[x]=x,说明从1到x的最短路使用了这条边,所以我们可以不建这条边.
(2)当pre[x]!=x,说明原点到达x的最短路径不是这条边,所以我们可以在新图中建立从1到x的边,边权为value.

Part3:该边的起点和终点均不为1.

(1)当pre[u]!=pre[v],说明原点到达两端点的最短路径是不同的,也就是说u到v的最短路径并不是通过这条边,这条可以填在新图中,所以我们可以在新图中建立一条从1到v,边权为dis[u]+value.
(2)当pre[u]==pre[v],在新图中保留原边。

最后的输出dis[1 + n]即可

这里连边比较复杂,我用了数据结构去连边。
参考代码如下
#include <cstdio>
#include <iostream>
#include <cmath>
#include <cstring>
#include <algorithm>
#define N 200005
#define fo(i,a,b) for (int i=a;i<=b;i++)
#define fd(i,a,b) for (int i=a;i>=b;i--)
#define INF 214748364using namespace std;
int Final[N],n,m;
int dis[N],d[N],Pre[N];
bool Flag[N];struct node
{int to,next,time;node(void){}node(int a,int b,int c) : to(a),next(b),time(c){}
};struct Q
{node Line[N];int Final[N],tot;
}e,e2;int read(int &n)
{char ch = ' ';int q = 0, w = 1;for (;(ch != '-') && ((ch < '0') || (ch> '9'));ch = getchar());if (ch == '-') w = -1,ch = getchar();for (; ch >= '0' && ch <= '9';ch = getchar()) q = q * 10 + ch - 48;n = q * w;return n;
}void Link(Q &e,int x,int y,int z)
{e.Line[++ e.tot] = node(y,e.Final[x],z),e.Final[x] = e.tot;
}void Spfa(Q &e)
{int l = 0 ,r = 1;    d[1] = 1;Flag[1] = true;while (l < r){int x = d[++ l];for (int i = e.Final[x];i;i = e.Line[i].next){int k = e.Line[i].to;if (dis[x] + e.Line[i].time < dis[k]){dis[k] = dis[x] + e.Line[i].time;if (x == 1) Pre[k] = k; else Pre[k] = Pre[x];if (!Flag[k]){Flag[k] = true;d[++ r] = k; }   }}Flag[x] = false;}
}int main()
{read(n);read(m);fo(i,1,m){int s,t,v,w;read(s),read(t),read(v),read(w);Link(e,s,t,v);Link(e,t,s,w);}    fo(i,1,n) dis[i] = INF;dis[1] = 0;Spfa(e);fo(i,1,n){int x = i;for (int k = e.Final[x];k;k = e.Line[k].next){int y = e.Line[k].to;if (y == 1){if (Pre[x] == x) Link(e2,x,n + 1,e.Line[k].time);else Link(e2,1,n+1,dis[x] + e.Line[k].time);}elseif (x == 1){if (Pre[y] != y) Link(e2,1,y,e.Line[k].time);}elseif (Pre[y] == Pre[x]) Link(e2,x,y,e.Line[k].time);else Link(e2,1,y,dis[x] + e.Line[k].time); }}fo(i,1,n + 1) dis[i] = INF;dis[1] = 0;Spfa(e2);if (dis[n + 1] == INF) printf("-1\n");else printf("%d\n",dis[n + 1]);return 0;
}

【NOIP2014模拟11.2A组】福慧双修相关推荐

  1. jzoj2702. 探险jzoj3917. 【NOIP2014模拟11.2A组】福慧双修

    Description 探险家小T好高兴!X国要举办一次溶洞探险比赛,获奖者将得到丰厚奖品哦!小T虽然对奖品不感兴趣,但是这个大振名声的机会当然不能错过! 比赛即将开始,工作人员说明了这次比赛的规则: ...

  2. 3917 【NOIP2014模拟11.2A组】福慧双修 (Standard IO)题解

    目录 目录 原题 Description Input Output Sample Input Sample Output Data Constraint 题解 40分 100分 模型转换 做法 I I ...

  3. 【NOIP2014模拟11.2B组】超氧化钾

    非常sb的一道题~比赛切掉的我~ Description 作为一个化学小考只有77分的同学,小W感觉很有压力,所以他决定搞化学.今天他开始研究超氧化钾,这是一种很神奇的离子化合物,在高温下空间结构是立 ...

  4. 【NOIP2014模拟11.1B组】吴传之火烧连营(tree)

    题目大意 对于一个序列,多次询问求在 xor K 的情况下最大值. 分析 我们将每一个数拆分成 2 进制,然后映射进一棵 trie 中,然后对于每个询问,根据异或的性质(1 xor 1=0,1 xor ...

  5. 【NOIP2014模拟11.1B组】吴传之火烧连营

    trie,动态开点. 我们可以将输入的a[],b[]全部看成二进制数. 然后按照二进制中的位置从大到小开始建trie. 如果trie不会的可以自己手动普及一下. 建好a[]的trie后,我们可以对于每 ...

  6. 3914. 【NOIP2014模拟11.2B组】人品问题

    Description 网上出现了一种高科技产品--人品测试器.只要你把你的真实姓名输入进去,系统将自动输出你的人品指数.yzx不相信自己的人品为0.经过了许多研究后,yzx得出了一个更为科学的人品计 ...

  7. JZOJ 3912. 【NOIP2014模拟11.2B组】超氧化钾

    Are you ready? 题目: 题意: 分析: 代码: 题目: 传送门 题意: 给定你xxx.yyy,求按照题目给出的z=xz=xz=x modmodmod 1+x1+x1+x modmodmo ...

  8. 3912. 【NOIP2014模拟11.2B组】超氧化钾

    Description 作为一个化学小考只有77分的同学,小W感觉很有压力,所以他决定搞化学.今天他开始研究超氧化钾,这是一种很神奇的离子化合物,在高温下空间结构是立方体,如下图所示.有一天教黄交给了 ...

  9. 【NOIP2014模拟11.2B组】人品问题

    Description 网上出现了一种高科技产品--人品测试器.只要你把你的真实姓名输入进去,系统将自动输出你的人品指数.yzx不相信自己的人品为0.经过了许多研究后,yzx得出了一个更为科学的人品计 ...

最新文章

  1. vue2.0通过Axios导出excel文件(解决乱码问题)
  2. Linux后台进程管理以及ctrl+z(挂起)、ctrl+c(中断)、ctrl+\(退出)和ctrl+d(EOF)的区别
  3. Web开发(一)·期末不挂之第四章·CSS语法基础(CSS选择器选择器优先级各类样式表的使用方法)
  4. Java多线程编程模式实战指南(三):Two-phase Termination模式--转载
  5. 链接器工具错误 LNK2019 必须在友元声明中显式指定模板参数
  6. centos 安装trace_前期的准备工作-MacOS Mojave 10.14.3 下安装CentOS 7及Bochs 002
  7. 套接字(socket)基本知识与工作原理
  8. 苹果App Store曝出Bug 你遇到了么?
  9. 《Android 第1行代码》读后感—第1章【开始启程,你的第一行Android代码】
  10. oracle出现数据坏块ORA-01578 ORA-01110 ORA-26040解决办法。
  11. 思维导图使用技巧:手把手教你怎么画思维导图
  12. 《人月神话(The Mythical Man-Month)》看清问题的本质:如果我们想解决问题,就必须试图先去理解它...
  13. qp_查看表的数据是否更新了指定的某一天数据
  14. Freebase中的基本概念
  15. Matlab入门:实现简单的数据剔除
  16. 【Python】解决使用 plt.savefig 保存图片时一片空白
  17. 键盘输入一个高精度的正整数n,去掉任意s个数字后剩下的数字按原左右次序将组成一个新的正整数。编程对给定的n和s,寻找一种方案,使得剩下的数最小
  18. MySQL(加强)06 -- 触发器(Trigger)
  19. Android 开发 VectorDrawable 矢量图 (三)矢量图动画
  20. 【愚公系列】2021年12月 VUE3-循环v-for

热门文章

  1. 1.Concurrent概述
  2. 旭荣管理软件怎么修改小票内容_PowerPhotos for Mac照片库管理软件
  3. 应用回归分析(知识点整理)(一)
  4. 【SpringBoot入门】SpringBoot的配置
  5. iNavFlight之MSP DJI协议飞控端请求应答
  6. 3D游戏建模学习就业会困难吗?10年资深游戏美术大拿分享就职面试心得
  7. 港科夜闻|香港科技大学史维校长及汪扬副校长出席“一流大学建设系列研讨会--2021”暨中国大学校长联谊会线上会议...
  8. 都这个点了,尽然还写博客啊,总结
  9. web scraper 爬取微博粉丝性别以及微博内容
  10. java float转换_Java float转换为String