原题链接

简化题意

一个无向连通图中将边分成了不同颜色(保证同种颜色联通),问从 \(b\) 到 \(e\) 最短需要经过几种颜色

思路

考虑因为同种颜色联通,可直接在读入的时候开两个 vector 分别存每个点属于的颜色及每种颜色有哪些点,又因为颜色数字可能跨度比较大,最好另开一个存颜色的种类

然后就是从 \(b\) 开始 BFS ,对每个点遍历它直连的所有颜色种类,然后遍历属于该颜色的所有点

小优化

发现存颜色的时候会将一条边连着的两个点都存进去,存点同理,也就是一个点可能会被同颜色存很多次且可能存很多个同颜色,这里开两个 map 去重可以大大降低复杂度

注意!!!

因为 codeforces 上可以 hack 别人的代码,所以赛后数据有卡 hash 表的,建议观看 这篇

CF 大佬的博客,防止自己的 hash 表被卡

开两个数组存遍历过的颜色块和节点,复杂度显然是线性的

代码

#include<bits/stdc++.h>
//#include<ext/pb_ds/assoc_container.hpp>
//#include<ext/pb_ds/hash_policy.hpp>
#define ll long long
using namespace std;
//using namespace __gnu_cxx;
//using namespace __gnu_pbds; struct custom_hash {
static uint64_t splitmix64(uint64_t x) {
// http://xorshift.di.unimi.it/splitmix64.c
x += 0x9e3779b97f4a7c15;
x = (x ^ (x >> 30)) * 0xbf58476d1ce4e5b9;
x = (x ^ (x >> 27)) * 0x94d049bb133111eb;
return x ^ (x >> 31);
} size_t operator()(uint64_t x) const {
static const uint64_t FIXED_RANDOM = chrono::steady_clock::now().time_since_epoch().count();
return splitmix64(x + FIXED_RANDOM);
}
}; const int N=4e5+10;
int T,n,m,b,e,ans;
bool fc[N],fl[N],fd[N];
queue<pair<int,int>>q;
vector<int>col[N],v[N],vec;
unordered_map<int,bool,custom_hash>mp1;
unordered_map<long long,bool,custom_hash>mp2;
inline void init()
{
while(!q.empty())
q.pop();
for(auto it : col[e])
fl[it]=false;
for(int i=1;i<=n;i++)
{
fd[i]=false;
col[i].clear();
}
for(auto it : vec)
{
fc[it]=false;
v[it].clear();
}
ans=1e9;
vec.clear();
mp1.clear();
mp2.clear();
return ;
}
inline void bfs(int x,int t)
{
fd[x]=true;
q.push({x,t});
while(!q.empty())
{
x=q.front().first;
t=q.front().second;
q.pop();
for(auto i : col[x])
{
if(fc[i])
continue;
if(fl[i])
{
ans=min(ans,t);
return ;
}
fc[i]=true;
for(auto j : v[i])
if(!fd[j])
{
fd[j]=true;
q.push({j,t+1});
}
}
}
return ;
}
int main()
{
cin>>T;
while(T--)
{
init();
scanf("%d%d",&n,&m);
for(int i=1,x,y,c;i<=m;i++)
{
scanf("%d%d%d",&x,&y,&c);
if(mp1.find(c)==mp1.end())
{
mp1[c]=1;
vec.push_back(c);
}
if(mp2.find(((ll)x<<32)|c)==mp2.end())
{
mp2[((ll)x<<32)|c]=1;
v[c].push_back(x);
col[x].push_back(c);
}
if(mp2.find(((ll)y<<32)|c)==mp2.end())
{
mp2[((ll)y<<32)|c]=1;
v[c].push_back(y);
col[y].push_back(c);
}
}
scanf("%d%d",&b,&e);
if(b==e)
{
printf("0\n");
continue;
}
for(auto it : col[e])
fl[it]=true;
bfs(b,1);
printf("%d\n",ans);
}
return 0;
}

题解:CF1941G Rudolf and Subway的更多相关文章

  1. 2016 Multi-University Training Contest 1 J.Subway

    Subway Time Limit: 7000/3500 MS (Java/Others)    Memory Limit: 262144/262144 K (Java/Others)Total Su ...

  2. 【POJ】【1635】Subway Tree Systems

    树的最小表示法 给定两个有根树的dfs序,问这两棵树是否同构 题解:http://blog.sina.com.cn/s/blog_a4c6b95201017tlz.html 题目要求判断两棵树是否是同 ...

  3. POJ 2502 Subway (最短路)

    Subway 题目链接: http://acm.hust.edu.cn/vjudge/contest/122685#problem/L Description You have just moved ...

  4. buaacoding_2018算法期末上机G题.地铁建设题解

    // 标注:本文旨在为博主确立一种题解的基本范式,以避免博主的题解流于AC代码的粘贴.此基本范式为:完整而简洁明了的思路及其推导说明,力图触及问题的本质并衍生对同类问题的思路分析,使得题解具有泛用性, ...

  5. Subway Pursuit (二分)(交互题)

    题目来源:codeforces1039B Subway Pursuit 题目大意: 在1到n里有一个运动的点,要求找到这个点,每次可以查询一个区间内有没有这个点,每次这个点往左或者往右移动1到k个位置 ...

  6. POJ2502:Subway(最短路)

    Subway Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 14634   Accepted: 4718 题目链接:http ...

  7. kuangbin带你飞 最短路 题解

    求一个图最短路边的办法.好像下面的那个有问题.单向边和双向边一定是有区别的.这个比较容易.参照该文的最短路网络流题目和连通图题目一题求最短路关节边 另外上述2个题目的代码好像有问题. 在UVALIVE ...

  8. Codeforces Beta Round #95 (Div. 2) D. Subway 边双联通+spfa

    D. Subway   A subway scheme, classic for all Berland cities is represented by a set of n stations co ...

  9. L - Subway(最短路spfa)

    L - Subway(最短路spfa) You have just moved from a quiet Waterloo neighbourhood to a big, noisy city. In ...

  10. HDU5732 Subway【树重心 树哈希】

    HDU5732 Subway 题意: 给出两棵大小为\(N\)的同构树,要求输出对应的节点 \(N\le 10^5\) 题解: 由于重心最多只有两个,找到重心之后以重心为根进行树哈希,找到相同哈希值的 ...

随机推荐

  1. KingbaseES 分区表修改字段类型

    KingbaseES普通表修改表结构请参考:KingbaseES变更表结构表重写问题 数据类型转换重写与不重写: varchar(x) 转换到 varchar(y) 当 y>=x,不需要重写. ...

  2. JVM—运行时数据区

    JVM-运行时数据区 运行时数据区概述 JVM运行时数据区如下图: 整个JVM构成里面,主要由三部分组成:类加载系统.运行时数据区.执行引擎. 按照线程使用情况和职责分成两大类: 线程独享(程序执行区 ...

  3. Advanced .Net Debugging 6:程序集加载器

    一.简介 这是我的<Advanced .Net Debugging>这个系列的第六篇文章.这篇文章的内容是原书的第二部分的[调试实战]的第四章.这章主要讲的是程序集加载器,比如:CLR 加 ...

  4. 记一次nginx服务异常-无法访问问题排查

    上一秒还好好地,突然下一秒nginx服务器就访问不了啦. 这让人很是疑惑,到底是什么原因导致的呢?问题如下 开始一步一步地排查问题. 尝试一:在windows电脑上使用telnet命令查看端口是否正常 ...

  5. #Splay#U137476 序列

    题目 给定长度为\(n\)的序列\(Ai\) ,我们将按照如下操作给\(Ai\) 排序, 先找到编号最小的所在位置\(x1\) ,将\([1,x1]\) 翻转, 再找到编号第二小的所在位置\(x2\) ...

  6. GitHub/GitLab 为不同的项目修改提交名字 user.name 和邮箱 user.email(附:批量处理脚本)

    背景 大疫情的背景下,家里的电脑需要同时支撑自己和公司的项目,根据 GitHub/GitLab 网站的提交记录上看,其是根据邮箱来辨识用户的,所以有必要分别针对不同的项目设置不同的 Git 名字(us ...

  7. OpenHarmony技术日全面解读3.1 Release版本,系统基础能力再升级

    4 月 25 日,OpenAtom OpenHarmony(以下简称"OpenHarmony")技术日在深圳举办,对 OpenHarmony 3.1 Release 版本核心技术进 ...

  8. Python生成测试数据--Faker的使用方法

    # 官方文档:https://faker.readthedocs.io/en/master/index.html # 安装:pip install Faker from faker import Fa ...

  9. 重学c#系列——DiagnosticListener [三十五]

    前言 简单介绍一下DiagnosticListener,一个比较常见的事件通知模型,可以说是事件发布订阅模型,常用于监控. 正文 直接编写代码: using System.Diagnostics; p ...

  10. c# 泛型原理(旧)

    前言 说起泛型可能很多人刚才看到的时候肯定会说牛逼啊,厉害啊,这东西少写了不少代码,我总结了泛型的一个优点,那就是少写代码,额,专业点吧. 优点:增加代码的重复利用率,代码重用. 先不讲原理吧,来讲下 ...