这道题最后没过,估计是痛失省一了,现在来补一下,当时思路是对的应该是代码出了问题导致样例没过最后nc的除了2,一直WA

题意:

给一张联通图,有两个导航系统,其中一个系统认为第i条边的权值是Pi,另一个系统认为是Qi(给定Pi和Qi),然后每个导航系统对于每条边i有个判定

其中一个是hero(vi)+Pi>hero(ui)会报警一次,另一个系统是a(vi)+Qi>a(ui)会报警一次,ui是边i的一个结点vi是另一个结点,让求一条两个系统警告次数相加最少的一条路径。

思路:

先从终点n作为起点跑两次最短路,一个按Pi为权值,求出每个节点v的hero(v),第二次以Qi为权值,求出每个节点v的a(v)。

然后遍历每条边,用警告次数作为权值从1作为起点再跑一次最短路求出结果即可。最短路的求法我用了Dij+堆优化。

这个改正过的代码只过了样例,没法实际测试了,有不对的地方还请大佬指正。

样例数据:

Sample input

5 7
3 4 7 1
1 3 2 20
1 4 17 18
4 5 25 3
1 2 10 1
3 5 4 14
2 4 6 5

Sample output

1

#include <bits/stdc++.h>
using namespace std; const int maxn = 1e4 + ;
const int maxm = 5e4 + ;
const int inf = 0x3f3f3f3f;
struct edge{
int to, wp, wq, ww, next;
} ed[maxm*];
int n, m, head[maxn], tot;
int hero[maxn], a[maxn], dis[maxn];
bool vis[maxn];
inline void add( int u, int v, int p, int q ){
ed[tot].to = v;
ed[tot].wp = p;
ed[tot].wq = q;
ed[tot].ww = ;
ed[tot].next = head[u];
head[u] = tot ++;
} inline void dij1(int s){
memset( vis, , sizeof(vis) );
memset( hero, inf, sizeof(hero) );
priority_queue< pair<int, int> > q;
vis[s] = ;
hero[s] = ;
q.push( make_pair( , s ) );
while( !q.empty() ){
int u = q.top().second;
q.pop();
for( int i=head[u]; i!=-; i=ed[i].next ){
int v = ed[i].to;
if( hero[v]>hero[u]+ed[i].wp ){
hero[v] = hero[u]+ed[i].wp;
if( !vis[v] ){
vis[v] = ;
q.push( make_pair( -hero[v], v ) );
}
}
}
}
} inline void dij2(int s){
memset( vis, , sizeof(vis) );
memset( a, inf, sizeof(a) );
priority_queue< pair<int, int> > q;
a[s] = ;
q.push( make_pair( , s ) );
while( !q.empty() ){
int u = q.top().second;
q.pop();
if( vis[u] ) continue;
vis[u] = ;
for( int i=head[u]; i!=-; i=ed[i].next ){
int v = ed[i].to;
if( a[v]>a[u]+ed[i].wq ){
a[v] = a[u]+ed[i].wq;
q.push( make_pair(-a[v], v) );
}
}
}
} inline void dij3( int s ){
memset( vis, , sizeof(vis) );
memset( dis, inf, sizeof(dis) );
priority_queue< pair<int, int> > q;
dis[s] = ;
q.push( make_pair( , s ) );
while( !q.empty() ){
int u = q.top().second;
q.pop();
if( vis[u] ) continue;
vis[u] = ;
for( int i=head[u]; i!=-; i=ed[i].next ){
int v = ed[i].to;
if( dis[v]>dis[u]+ed[i].ww ){
dis[v] = dis[u]+ed[i].ww;
q.push( make_pair( -dis[v], v ) );
}
}
}
} inline void bfs(int s){
queue<int> q;
memset( vis, , sizeof(vis) );
vis[s] = ;
q.push(s);
while( !q.empty() ){
int u = q.front();
q.pop();
for( int i=head[u]; i!=-; i=ed[i].next ){
int v = ed[i].to;
if( !vis[v] ){
vis[v] = ;
if( hero[v]+ed[i].wp>hero[u] ) ed[i].ww ++;
if( a[v]+ed[i].wq>a[u] ) ed[i].ww ++;
}
}
}
} int main(){
// freopen("in.txt", "r", stdin);
tot = ;
memset( head, -, sizeof(head) );
scanf("%d%d", &n, &m);
for( int i=; i<m; i++ ){
int u, v, p, q;
scanf("%d%d%d%d", &u, &v, &p, &q);
add( u, v, p, q );
add( v, u, p, q );
}
dij1(n);
dij2(n);
//注释掉的就是当时写的错误遍历边的代码
// for( int i=1; i<=n; i++ ){
// for( int j=head[i]; j!=-1; j=ed[j].next ){
// if( ed[j].wp+hero[ed[j].to]>hero[i] ) ed[j].ww ++;
// if( ed[j].wq+a[ed[j].to]>a[i] ) ed[j].ww ++;
// }
// }
bfs(); //应该从1开始向外bfs遍历边,即可找出正确答案
dij3();
printf("%d\n", dis[n]); return ;
}

2019安徽省程序设计竞赛 D.自驾游(最短路)的更多相关文章

  1. 2019安徽省程序设计竞赛 I.你的名字(序列自动机)

    这题和今年南昌邀请网络预选赛M题很像啊,不过主串数量不是一个了 都是在主串中判断子串是不是属于主串的一个子序列 #include <iostream> #include <cstri ...

  2. 2019中山大学程序设计竞赛 Triangle

    今天水了一发hdu上的中山校赛 这个题交了将近十遍才过...... 就是说给 n 个木棍,如果能找出3个能组成三角形的木棍就输出yes 反之输出no 乍一看很简单 一个排序遍历一遍就好了 但是n值太大 ...

  3. 2019中山大学程序设计竞赛-Monitor

    题目地址 题目大意:给你一个n*m的矩形,在这个矩形内告诉你p个矩形(左下角和右上角坐标),问你q个问题,每次也是给你一个矩形(左下角和右上角坐标),问你每个矩形是否可以被开始给的p个矩形完全覆盖. ...

  4. 2019中山大学程序设计竞赛(重现赛) Clumsy Keke

    Problem Description Keke is currently studying engineering drawing courses, and the teacher has taug ...

  5. 吉首大学2019年程序设计竞赛(重现赛)D - 数列求和(嘤雄难度)

    链接:https://ac.nowcoder.com/acm/contest/992/D $a_{i}=\dfrac {3a_{i-1}-a_{i-2}}{2}+i+1$ 移项再化一下 $a_{i}- ...

  6. 吉首大学2019年程序设计竞赛(重现赛)- A SARS病毒 (矩阵,欧拉降幂)

    题目链接:https://ac.nowcoder.com/acm/contest/992/A 题意:求出长度为n的字符串个数,字符串由A.C.G.T组成,其中A和C必须成对出现. 思路:我们规定:   ...

  7. 吉首大学2019年程序设计竞赛(重现赛)-K(线段树)

    题目链接:https://ac.nowcoder.com/acm/contest/992/K 题意:给一个大小为1e5的数组,由0 1组成,有两种操作,包括区间修改,将一段区间内的0换成1,1换成0; ...

  8. 吉首大学2019年程序设计竞赛(重现赛)-J(树形DP)

    题目链接:https://ac.nowcoder.com/acm/contest/992/J 题意:题意很清晰,就是求任意两点距离的和,结果对1e9+7取模. 思路:裸的树形DP题,一条边的贡献值=这 ...

  9. 吉首大学2019年程序设计竞赛-F 天花乱坠

    题目链接:https://ac.nowcoder.com/acm/contest/992/F 题意:给定正n边形,边长为100,以每条边的中点连线构成新的正n边形,无限循环下去,求所有边的长度和. 思 ...

随机推荐

  1. leetcode刷题系列(一) 26题 删除排序数组中的重复项

    题干 给定一个排序数组,你需要在原地删除重复出现的元素,使得每个元素只出现一次,返回移除后数组的新长度. 不要使用额外的数组空间,你必须在原地修改输入数组并在使用 O(1) 额外空间的条件下完成. 示 ...

  2. 打包工具Gradle

    Gradle Gradle是一个基于Apache Ant和Apache Maven概念的项目自动化建构工具.它使用一种基于Groovy的特定领域语言来声明项目设置,而不是传统的XML.当前其支持的语言 ...

  3. 【layui】获取layui弹窗的index并关闭

    var index = parent.layer.getFrameIndex(window.name); //获取窗口索引 parent.layer.close(index); // 关闭当前laye ...

  4. OpenLDAP + phpLDAPadmin

    一.基础设置 1.1 环境说明 Centos 7.5 openldap 1.2 关闭防火墙和selinux setenforce sed -i 's/SELINUX=enforcing/SELINUX ...

  5. 机器学习中什么是端到端的学习(end-to-end learning)?

    相对于深度学习,传统机器学习的流程往往由多个独立的模块组成,比如在一个典型的自然语言处理(Natural Language Processing)问题中,包括分词.词性标注.句法分析.语义分析等多个独 ...

  6. 74HC573锁存器应用(附英文手册)

    锁存器(LATCH)概念 锁存器(Latch)是一种对脉冲电平敏感的存储单元电路,它们可以在特定输入脉冲电平作用下改变状态. 锁存,就是把信号暂存以维持某种电平状态. 锁存器作用: 缓存 完成高速的控 ...

  7. Codeforces Round #580 (Div. 1) A-E

    Contest Page A Tag:构造 将$a_i$看做一个无穷数列,$i > 2n$时$a_i = a_{i - 2n}$.设$sgn_i = \sum\limits_{j=i+1}^{i ...

  8. C# 练习题 有一对兔子,从出生后第3个月起每个月都生一对兔子,小兔子长到第三个月后每个月又生一对兔子,假如兔子都不死,问每个月的兔子总数为多少?

    题目:古典问题:有一对兔子,从出生后第3个月起每个月都生一对兔子,小兔子长到第三个月后每个月又生一对兔子,假如兔子都不死,问每个月的兔子总数为多少?程序分析: 兔子的规律为数列1,1,2,3,5,8, ...

  9. (转)消息队列 Kafka 的基本知识及 .NET Core 客户端

    原文地址:https://www.cnblogs.com/savorboard/p/dotnetcore-kafka.html 前言 最新项目中要用到消息队列来做消息的传输,之所以选着 Kafka 是 ...

  10. sqlserver安装教程

    1 安装步骤:http://jingyan.baidu.com/article/359911f573f71657fe030603.html 2 当提示装载第二张光盘时,在DAEMON Tools中把第 ...