noip模拟赛多校第八场 T3 遥控机器人 (最短路 + 技巧拆点)

2023-11-06 20:12

本文主要是介绍noip模拟赛多校第八场 T3 遥控机器人 (最短路 + 技巧拆点),希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

题面

在这里插入图片描述

简要题意:
        给你一个 n n n 个点 m m m 条边的图。边 i i i 有颜色 c i c_i ci。你可以选择一些边改变它们的颜色成为区间 [ 1 , m ] [1, m] [1,m] 中的任意颜色,改变一条边 i i i 一次的代价是 w i w_i wi。询问你能否在一些改变操作后使得可以从 1 1 1 号点,每次只经过当前点的 特殊边 到达 n n n。特殊边的定义是 对于当前点而言,特殊边的颜色在该点所有出边中有且仅出现一条。 如果可以,输出最小代价。否则输出 − 1 -1 1

分析:

        凭感觉是一道最短路的题。

        首先有一个性质:因为颜色的区间与边数相同,所以如果要改变一条边,那么可以把它变成一个任何别的边都不会再变成的颜色。换言之, 如果要花费代价改变某一条边的颜色,那么可以把它变成无色,并且这样是最优的

        接下来我们考虑如果一条边 ( u , v ) (u, v) (u,v) 的颜色是 c c c,花费是 w w w。我们从 u u u v v v 经过它花费代价有几种情况:

        1. u u u 的出边中是 c c c 颜色的只有一条,那么代价是 0 0 0

        2. u u u 的出边中 c c c 颜色的边有多条,改变这条边的颜色至无色,花费是 w w w

        3. u u u 的出边中 c c c 颜色的边有多条,改变不改变它的颜色,改变其它边的颜色至无色。
            花费是 v a l u , c − w val_{u, c} - w valu,cw v a l u , c val_{u, c} valu,c 代表所有 u u u 的出边中颜色是 c c c 的边的代价之和。

        不难发现,情况 1 1 1 可以归到情况 3 3 3 中。

        我们考虑把这两种代价看做两种边权跑最短路会有什么问题:

        如果按照情况 3 3 3 u u u v v v,我们考虑会不会存在一个问题:按照情况 3 3 3 我们需要把其它颜色也为 c c c 的边都改成无色,那么把它变成无色但是却不记录会不会影响后面答案的计算呢?
)

        蓝色点表示最优路径的点,红色的边表示情况 3 3 3 中染成无色的边,它们的颜色是 c c c。黑色的边表示最优路径的边。那么如果出现上图的情况(从 5 5 5 号点走到 1 1 1 号点),那么 2 2 2 号点到 1 1 1 号点似乎是不需要花费的,因为在从 4 4 4 号点到 3 3 3 号点的时候就把那条颜色为 c c c 的边染成了无色。但是我们按照上面的规则进行的话,如果从 2 2 2 3 3 3 还使用情况 3 3 3,显然会多算一个代价。

        但是深入思考一下,这种情况不会发生。因为这样的路径一定不是最优路径。如果按照上图的走法,那么 ( 2 , 4 ) (2,4) (2,4) ( 6 , 4 ) (6, 4) (6,4) ( 4 , 7 ) (4, 7) (4,7) 的代价都会被算。实际上如果我们直接选择路径 5 → 4 → 2 → 1 5 \to 4 \to 2 \to 1 5421,并且 ( 4 , 2 ) (4, 2) (4,2) 使用情况 2 2 2 ( 2 , 1 ) (2, 1) (2,1) 使用情况 3 3 3 肯定更加优秀。

        这也就意味着: 如果我们能够通过某种方式处理好情况 2 2 2 带来的影响(即把边染成无色的影响),那么按照上面的规则跑最短路就是对的

        如果按照情况 2 2 2 经过一条颜色为 c c c 的边 从 u u u v v v,那么 ( u , v ) (u, v) (u,v) 这条边颜色的改变可能会影响从 v v v k k k 经过一条颜色为 c c c 按照情况 3 3 3 所花费的代价。根据这个问题,我们考虑 拆点

        有一个很暴力的想法是我们把每一个点拆成 m + 1 m + 1 m+1 个点:若有三个点 a a a, b b b , c c c a a a b b b 经过一条颜色为 x x x 的边,当使用情况 2 2 2 的时候,可以从 a a a 走向 b x b_x bx,代价为 0 0 0 b x b_x bx必须继续沿着颜色x使用情况 3 3 3 走向其他点。每一个点的 0 0 0 状态表示 没有限制。这样我们就解决了维护信息的问题。但是复杂度好像有点问题。

        我们考虑实际上一个点没有必要开 m m m 个点,只需要对每个点开其存在的颜色数个点就行了。一条边能够提供给两个点分别提供 1 1 1 个点,所以总点数是 2 m + n 2m + n 2m+n。然后建图跑最短路即可。时间复杂度 O ( ( n + m ) l o g 2 ( n + m ) ) O((n + m)log_2(n + m)) O((n+m)log2(n+m))。常数有亿点大。

CODE:

#include<bits/stdc++.h>//拆点   把点的状态拆一下 
using namespace std;
const int N = 1e5 + 10;
const int M = 2e5 + 10;
const int T = 2 * N + M * 2;
typedef pair< int, int > PII;
typedef long long LL;
inline int read(){int x = 0, f = 1; char c = getchar();while(!isdigit(c)){if(c == '-') f = -1; c = getchar();}while(isdigit(c)){x = (x << 1) + (x << 3) + (c ^ 48); c = getchar();}return x * f;
}
int u, v, c;
int n, m, head[T], ut[M], vt[M], ct[M], tot, len;//最多T个点
bool vis[T];
LL wt[M], dis[T], res, w; 
map< PII, int > rk;
map< PII, LL > val;
struct edge{int v, last;LL w;
}E[M * 8 + 10000];
void add(int u, int v, LL w){E[++len].v = v;E[len].last = head[u];E[len].w = w;head[u] = len;
}
struct state{int x; LL w;friend bool operator < (state a, state b){return a.w > b.w;}
};
void dijkstra(int s){priority_queue< state > q;q.push((state){s, 0});while(!q.empty()){state u = q.top(); q.pop();int x = u.x;if(vis[x]) continue;vis[x] = 1;for(int i = head[x]; i; i = E[i].last){int v = E[i].v; LL w = E[i].w;if(dis[v] > dis[x] + w){dis[v] = dis[x] + w;q.push((state){v, dis[v]});}}}
}
int main(){n = read(), m = read();for(int i = 1; i <= n; i++){rk[make_pair(i, 0)] = ++tot;}for(int i = 1; i <= m; i++){u = read(), v = read(); c = read(), w = 1LL * read();if(!rk[make_pair(u, c)]) rk[make_pair(u, c)] = ++tot;if(!rk[make_pair(v, c)]) rk[make_pair(v, c)] = ++tot;val[make_pair(u, c)] += w;val[make_pair(v, c)] += w;ut[i] = u, vt[i] = v, wt[i] = w, ct[i] = c;}for(int i = 1; i <= m; i++){int u = ut[i], v = vt[i], c = ct[i], w = wt[i];add(rk[make_pair(u, 0)], rk[make_pair(v, 0)], w);//改变颜色,不做限制 add(rk[make_pair(u, 0)], rk[make_pair(v, c)], 0);//改变颜色,必须限制 add(rk[make_pair(u, c)], rk[make_pair(v, 0)], val[make_pair(u, c)] - w);add(rk[make_pair(u, 0)], rk[make_pair(v, 0)], val[make_pair(u, c)] - w);add(rk[make_pair(v, 0)], rk[make_pair(u, 0)], w);//改变颜色,不做限制 add(rk[make_pair(v, 0)], rk[make_pair(u, c)], 0);//改变颜色,必须限制 add(rk[make_pair(v, c)], rk[make_pair(u, 0)], val[make_pair(v, c)] - w);add(rk[make_pair(v, 0)], rk[make_pair(u, 0)], val[make_pair(v, c)] - w);}memset(dis, 0x3f, sizeof dis);dis[rk[make_pair(1, 0)]] = 0;dijkstra(rk[make_pair(1, 0)]);res = dis[rk[make_pair(n, 0)]];if(res == 0x3f3f3f3f3f3f3f3f) res = -1;printf("%lld\n", res);return 0;
}

这篇关于noip模拟赛多校第八场 T3 遥控机器人 (最短路 + 技巧拆点)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/358817

相关文章

Python通过模块化开发优化代码的技巧分享

《Python通过模块化开发优化代码的技巧分享》模块化开发就是把代码拆成一个个“零件”,该封装封装,该拆分拆分,下面小编就来和大家简单聊聊python如何用模块化开发进行代码优化吧... 目录什么是模块化开发如何拆分代码改进版:拆分成模块让模块更强大:使用 __init__.py你一定会遇到的问题模www.

MyBatis 动态 SQL 优化之标签的实战与技巧(常见用法)

《MyBatis动态SQL优化之标签的实战与技巧(常见用法)》本文通过详细的示例和实际应用场景,介绍了如何有效利用这些标签来优化MyBatis配置,提升开发效率,确保SQL的高效执行和安全性,感... 目录动态SQL详解一、动态SQL的核心概念1.1 什么是动态SQL?1.2 动态SQL的优点1.3 动态S

电脑win32spl.dll文件丢失咋办? win32spl.dll丢失无法连接打印机修复技巧

《电脑win32spl.dll文件丢失咋办?win32spl.dll丢失无法连接打印机修复技巧》电脑突然提示win32spl.dll文件丢失,打印机死活连不上,今天就来给大家详细讲解一下这个问题的解... 不知道大家在使用电脑的时候是否遇到过关于win32spl.dll文件丢失的问题,win32spl.dl

电脑报错cxcore100.dll丢失怎么办? 多种免费修复缺失的cxcore100.dll文件的技巧

《电脑报错cxcore100.dll丢失怎么办?多种免费修复缺失的cxcore100.dll文件的技巧》你是否也遇到过“由于找不到cxcore100.dll,无法继续执行代码,重新安装程序可能会解... 当电脑报错“cxcore100.dll未找到”时,这通常意味着系统无法找到或加载这编程个必要的动态链接库

如何关闭 Mac 触发角功能或设置修饰键? mac电脑防止误触设置技巧

《如何关闭Mac触发角功能或设置修饰键?mac电脑防止误触设置技巧》从Windows换到iOS大半年来,触发角是我觉得值得吹爆的MacBook效率神器,成为一大说服理由,下面我们就来看看mac电... MAC 的「触发角」功能虽然提高了效率,但过于灵敏也让不少用户感到头疼。特别是在关键时刻,一不小心就可能触

CSS模拟 html 的 title 属性(鼠标悬浮显示提示文字效果)

《CSS模拟html的title属性(鼠标悬浮显示提示文字效果)》:本文主要介绍了如何使用CSS模拟HTML的title属性,通过鼠标悬浮显示提示文字效果,通过设置`.tipBox`和`.tipBox.tipContent`的样式,实现了提示内容的隐藏和显示,详细内容请阅读本文,希望能对你有所帮助... 效

前端bug调试的方法技巧及常见错误

《前端bug调试的方法技巧及常见错误》:本文主要介绍编程中常见的报错和Bug,以及调试的重要性,调试的基本流程是通过缩小范围来定位问题,并给出了推测法、删除代码法、console调试和debugg... 目录调试基本流程调试方法排查bug的两大技巧如何看控制台报错前端常见错误取值调用报错资源引入错误解析错误

mysql线上查询之前要性能调优的技巧及示例

《mysql线上查询之前要性能调优的技巧及示例》文章介绍了查询优化的几种方法,包括使用索引、避免不必要的列和行、有效的JOIN策略、子查询和派生表的优化、查询提示和优化器提示等,这些方法可以帮助提高数... 目录避免不必要的列和行使用有效的JOIN策略使用子查询和派生表时要小心使用查询提示和优化器提示其他常

Apache伪静态(Rewrite).htaccess文件详解与配置技巧

《Apache伪静态(Rewrite).htaccess文件详解与配置技巧》Apache伪静态(Rewrite).htaccess是一个纯文本文件,它里面存放着Apache服务器配置相关的指令,主要的... 一、.htAccess的基本作用.htaccess是一个纯文本文件,它里面存放着Apache服务器

Spring中@Lazy注解的使用技巧与实例解析

《Spring中@Lazy注解的使用技巧与实例解析》@Lazy注解在Spring框架中用于延迟Bean的初始化,优化应用启动性能,它不仅适用于@Bean和@Component,还可以用于注入点,通过将... 目录一、@Lazy注解的作用(一)延迟Bean的初始化(二)与@Autowired结合使用二、实例解