[abc302f] Merge Set
F - Merge Set
显然要建图
首先,我们有一个粗略的想法,对于同一集合\(S_i\)内的元素,\(S_{i,j}\)与\(S_{i,j+1}\)间连一条无向的标号为\(i\)的边
那么题目显然是要我们跑最短路,若到达\(x\)的边为\(i\),然后从\(x\)向外走到点\(y\),走的边若还为\(i\),那么代价为\(0\),否则代价为\(1\)
也就是说,换边走需要\(1\)的贡献
所以考虑用集合\(S_i\)连向所有的\(S_{i,j}\),因为不换边代价为\(0\),所以\(S_i\rightarrow S_{i,j}\)的权值为\(0\),而换边走代价为\(1\),也就意味着若当前边的类型为\(S_i\),且当前点为\(S_{i,p}\),那么我们要换另一种类型的边走,也就是要从\(S_{i,p}\)走到\(S_j\)(\(S_{i,j}\in S_j\)),这时需要\(1\)的代价,所以\(S_{i,j}\rightarrow S_i\)的权值为\(1\)
那么只需要建立一个起点\(S\)连向所有包含了1的集合,终点\(T\)就是M,\(S\)到\(T\)的最短路就是所求的答案
#include<bits/stdc++.h>
using namespace std;
const int N=4e5+5,M=5e5+5,INF=1e9;
int n,m,S,T;
int dis[N];
bool vis[N];
int head[N],cnt=1;
struct node{
int nxt,v,val;
}tree[(M<<1)+(N>>1)];
void add(int u,int v,int val){
tree[++cnt]={head[u],v,val},head[u]=cnt;
}
queue<int> q;
void solve(){
for(int i=1;i<=T;++i) dis[i]=INF;
q.push(S);
while(q.size()){
int u=q.front(); vis[u]=false,q.pop();
for(int i=head[u],v;i;i=tree[i].nxt)
if(dis[v=tree[i].v]>dis[u]+tree[i].val){
dis[v]=dis[u]+tree[i].val;
if(!vis[v]) q.push(v),vis[v]=true;
}
}
}
int main(){
scanf("%d%d",&n,&m),S=n+m+1,T=n+m;
for(int i=1,a,x;i<=n;++i){
scanf("%d",&a);
while(a--){
scanf("%d",&x),add(i,x+n,0),add(x+n,i,1);
if(x==1) add(S,i,0);
}
}
solve();
if(dis[T]==INF) printf("-1\n");
else printf("%d\n",dis[T]);
return 0;
}
[abc302f] Merge Set的更多相关文章
- [算法]——归并排序(Merge Sort)
归并排序(Merge Sort)与快速排序思想类似:将待排序数据分成两部分,继续将两个子部分进行递归的归并排序:然后将已经有序的两个子部分进行合并,最终完成排序.其时间复杂度与快速排序均为O(nlog ...
- SQL 提示介绍 hash/merge/concat union
查询提示一直是个很有争议的东西,因为他影响了sql server 自己选择执行计划.很多人在问是否应该使用查询提示的时候一般会被告知慎用或不要使用...但是个人认为善用提示在不修改语句的条件下,是常用 ...
- Merge Sorted Array
Given two sorted integer arrays nums1 and nums2, merge nums2 into nums1 as one sorted array. Note:Yo ...
- SQL Tuning 基础概述06 - 表的关联方式:Nested Loops Join,Merge Sort Join & Hash Join
nested loops join(嵌套循环) 驱动表返回几条结果集,被驱动表访问多少次,有驱动顺序,无须排序,无任何限制. 驱动表限制条件有索引,被驱动表连接条件有索引. hints:use_n ...
- Git 少用 Pull 多用 Fetch 和 Merge
本文有点长而且有点乱,但就像Mark Twain Blaise Pascal的笑话里说的那样:我没有时间让它更短些.在Git的邮件列表里有很多关于本文的讨论,我会尽量把其中相关的观点列在下面. 我最常 ...
- Merge 的小技巧
今天跟大家分享一下搬动数据使用Merge的方法. 有些时候,当我们做数据搬动的时候,有时候做测试啊,换对象啊,就会存在有时候外键存在,不知道怎么对应的关系.比如我现在有架构相同的两组table , A ...
- [LeetCode] Merge Sorted Array 混合插入有序数组
Given two sorted integer arrays A and B, merge B into A as one sorted array. Note:You may assume tha ...
- [LeetCode] Merge Intervals 合并区间
Given a collection of intervals, merge all overlapping intervals. For example, Given [1,3],[2,6],[8, ...
- [LeetCode] Merge k Sorted Lists 合并k个有序链表
Merge k sorted linked lists and return it as one sorted list. Analyze and describe its complexity. 这 ...
- [LeetCode] Merge Two Sorted Lists 混合插入有序链表
Merge two sorted linked lists and return it as a new list. The new list should be made by splicing t ...
随机推荐
- Delphi CheckListBox 用法
for i := CheckListBox1.Items.Count-1 downto 0 do //从后面往前面删 begin if CheckListBox1.Checked[i] then // ...
- BUUCTF---古典密码知多少
题目 知识 一共给出四种古典密码,分别是:猪圈密码.圣堂武士密码.标准银河字母.栅栏密码 猪圈之前有介绍 圣: 标准银河字母 更多加密方式 解题 对照解密 FGCPFLIRTUASYON 再使用栅栏 ...
- Win10资源管理器导航窗格显示/隐藏项目-注册表
一.隐藏快速访问 HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer HubMode(类型:REG_DWORD) ...
- Linux C线程读写锁深度解读 | 从原理到实战(附实测数据)
Linux C线程读写锁深度解读 | 从原理到实战(附实测数据) 读写锁练习:主线程不断写数据,另外两个线程不断读,通过读写锁保证数据读取有效性. 代码实现如下: #include <stdio ...
- Mybatis三大执行器
目录 1.执行器介绍 执行器的选择入口 设置执行器两种方式 全局配置(不建议) 局部设置(建议) 2.三个执行器区别 SimpleExecutor ReuseExecutor BatchExecuto ...
- Eclipse 安装Server-Apache Tomcat 选择(Tomcat 9.0选项)
1.打开组件安装 Eclipse→Help→Install New Software 2.输入当前eclipse对应版本(例如:2022-06),选择提示的官方路径 3.选择最底下的Web, XML, ...
- macOS终端修改DNS
以WiFi为例 networksetup -listallnetworkservices networksetup -setdnsservers Wi-Fi 8.8.8.8 networksetup ...
- 多线程——ThreadPool
参考:第三节:ThreadPool的线程开启.线程等待.线程池的设置.定时功能 - Yaopengfei - 博客园 (cnblogs.com) C# AppDomain 详解_勇于尝试,却要三思后行 ...
- MIUI系统,APKMirror Installer安装apkm的时候提示app installation failed Installation aborted解决方案
场景 我的手机是MIUI系统,通过APKMirror Installer安装apkm的时候提示app installation failed Installation aborted. 本来不想装了, ...
- 代码随想录第二十一天 | Leecode 669. 修剪二叉搜索树、108. 将有序数组转换为二叉搜索树、538. 把二叉搜索树转换为累加树
Leecode 669. 修剪二叉搜索树 题目描述 给你二叉搜索树的根节点 root ,同时给定最小边界low 和最大边界 high.通过修剪二叉搜索树,使得所有节点的值在[low, high]中.修 ...