Gym 101170I Iron and Coal(BFS + 思维)题解
题意:有一个有向图,有些点是煤,有些点是铁,但不会同时有铁和煤。现在我要从1出发,占领可以到达的点。问最少占领几个点能同时拥有一个煤和一个铁(1不用占领)。
思路:思路很秀啊。我们从1往外bfs,得到所有点到1的最短路dis[i][0],然后从所有煤跑bfs得到所有点到煤的最短路dis[i][1],我们再从所有铁跑bfs得到所有点到铁的最短路dis[i][2],那么dis[i][0] + dis[i][1] + dis[i][2]就是以i为分界点分别前往煤和铁的占领的最小距离。那么答案就是min{ dis[i][0] + dis[i][1] + dis[i][2] }。
代码:
#include<cmath>
#include<set>
#include<map>
#include<queue>
#include<cstdio>
#include<vector>
#include<cstring>
#include <iostream>
#include<algorithm>
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
const int maxn = 1e5 + 10;
const ull seed = 131;
const int INF = 0x3f3f3f3f;
const int MOD = 1e9 + 7;
int n, m, k;
int iron[maxn], coal[maxn], vis[maxn];
vector<int> G[maxn], g[maxn];
int dis[maxn][3];
struct node{
int x;
int step;
};
void bfs1(){
for(int i = 1; i <= n; i++) vis[i] = 0;
queue<node> q;
while(!q.empty()) q.pop();
vis[1] = 1;
dis[1][0] = 0;
node a, b;
a.x = 1, a.step = 0;
q.push(a);
while(!q.empty()){
a = q.front();
q.pop();
for(int i = 0; i < G[a.x].size(); i++){
int v = G[a.x][i];
if(vis[v]) continue;
vis[v] = 1;
dis[v][0] = a.step + 1;
b.x = v, b.step = a.step + 1;
q.push(b);
}
}
}
void bfs2(){
for(int i = 1; i <= n; i++) vis[i] = 0;
queue<node> q;
while(!q.empty()) q.pop();
node a, b;
for(int i = 1; i <= n; i++){
if(iron[i]){
vis[i] = 1;
dis[i][1] = 0;
a.x = i, a.step = 0;
q.push(a);
}
}
while(!q.empty()){
a = q.front();
q.pop();
for(int i = 0; i < g[a.x].size(); i++){
int v = g[a.x][i];
if(vis[v]) continue;
vis[v] = 1;
dis[v][1] = a.step + 1;
b.x = v, b.step = a.step + 1;
q.push(b);
}
}
}
void bfs3(){
for(int i = 1; i <= n; i++) vis[i] = 0;
queue<node> q;
while(!q.empty()) q.pop();
node a, b;
for(int i = 1; i <= n; i++){
if(coal[i]){
vis[i] = 1;
dis[i][2] = 0;
a.x = i, a.step = 0;
q.push(a);
}
}
while(!q.empty()){
a = q.front();
q.pop();
for(int i = 0; i < g[a.x].size(); i++){
int v = g[a.x][i];
if(vis[v]) continue;
vis[v] = 1;
dis[v][2] = a.step + 1;
b.x = v, b.step = a.step + 1;
q.push(b);
}
}
}
int main(){
scanf("%d%d%d", &n, &m, &k);
for(int i = 1; i <= n; i++){
iron[i] = coal[i] = 0;
G[i].clear();
g[i].clear();
memset(dis[i], INF, sizeof(dis[i]));
}
for(int i = 1; i <= m; i++){
int u;
scanf("%d", &u);
iron[u] = 1;
}
for(int i = 1; i <= k; i++){
int u;
scanf("%d", &u);
coal[u] = 1;
}
for(int i = 1; i <= n; i++){
int p, u, v;
scanf("%d", &p);
u = i;
while(p--){
scanf("%d", &v);
G[u].push_back(v);
g[v].push_back(u);
}
}
bfs1();
bfs2();
bfs3();
int ans = INF;
for(int i = 1; i <= n; i++){
if(dis[i][0] == INF || dis[i][1] == INF || dis[i][2] == INF) continue;
ans = min(ans, dis[i][0] + dis[i][1] + dis[i][2]);
}
if(ans < INF) printf("%d\n", ans);
else printf("impossible\n");
return 0;
}
Gym 101170I Iron and Coal(BFS + 思维)题解的更多相关文章
- DFS/BFS+思维 HDOJ 5325 Crazy Bobo
题目传送门 /* 题意:给一个树,节点上有权值,问最多能找出多少个点满足在树上是连通的并且按照权值排序后相邻的点 在树上的路径权值都小于这两个点 DFS/BFS+思维:按照权值的大小,从小的到大的连有 ...
- Gym 100971A Treasure Island BFS 思维题
A - Treasure Island Time Limit:2000MS Memory Limit:262144KB 64bit IO Format:%I64d & %I64 ...
- Gym - 101572D Distinctive Character bfs 思维
题目传送门 题目大意: 给出n个01串,让你构造一个字符串,使这个字符串和这些字符串中相似程度最高 尽可能低.如果两个字符串对应位置相同,则相似程度加一. 思路: 每一个01串更改自己的一部分后,都可 ...
- Codeforces Gym101170I:Iron and Coal(建多幅图+多次BFS)***
题目链接 题意 有n个点,其中有m个点是铁矿,k个点是煤,从1号点出发,你可以派一些士兵跑向不同的点,问占领至少一个铁矿和一个煤的时候,最少需要占领多少个点. 思路 建两幅图,其中一幅是正向边,一幅是 ...
- Codeforces Gym 100187E E. Two Labyrinths bfs
E. Two Labyrinths Time Limit: 20 Sec Memory Limit: 256 MB 题目连接 http://codeforces.com/gym/100187/prob ...
- Gym - 100187E E - Two Labyrinths —— bfs
题目链接:http://codeforces.com/gym/100187/problem/E 题解:一开始做的时候是将两幅图合并,然后直接bfs看是否能到达终点.但这种做法的错的,因为走出来的路对于 ...
- ACM: Gym 101047E Escape from Ayutthaya - BFS
Gym 101047E Escape from Ayutthaya Time Limit:2000MS Memory Limit:65536KB 64bit IO Format:%I6 ...
- Gym 101617J Treasure Map(bfs暴力)
http://codeforces.com/gym/101617/attachments 题意:给出一个图,每个顶点代表一个金矿,每个金矿有g和d两个值,g代表金矿初始的金子量,d是该金矿每天的金子量 ...
- 逃离迷宫(BFS)题解
Problem Description 给定一个m × n (m行, n列)的迷宫,迷宫中有两个位置,gloria想从迷宫的一个位置走到另外一个位置,当然迷宫中有些地方是空地,gloria可以穿越,有 ...
随机推荐
- IOC技术在前端项目中的应用
目录 背景 什么是IOC 如何实现一个IOC 第一步:实现一个容器 第二步:用好装饰器 第三步:使用容器 扩展和展望 最后 背景 前端发展至今已经过去30余年,前端应用领域在不断壮大的过程中,也变得越 ...
- Mybatis【15】-- Mybatis一对一多表关联查询
注:代码已托管在GitHub上,地址是:https://github.com/Damaer/Mybatis-Learning ,项目是mybatis-11-one2one,需要自取,需要配置maven ...
- CentOS 7.4通过rpm包离线安装 Mysql8.0并部署主从复制(附从库备份脚本)
一. 部署MySQL (两个节点都做) 下载 rpm包 wget https://goodrain-pkg.oss-cn-shanghai.aliyuncs.com/mysql8.rpm tar xv ...
- USB2514集线器调试总结
一般的MCU不会留有太多的USB口,但在实际项目中又会遇到需要很多个USB口的情况,这时就会用到USB集线器来扩展USB口了.USB2514这个芯片是我在工作中用的比较多的,但是问题很多,从来没有调稳 ...
- 前端面试准备笔记之JavaScript(04)
01. DOM的本质 xml是一种可扩展的标记性语言,可扩展就是可以描述任何结构的数据,他是一棵树,可以自定义标签,可以自己扩展. html也是一种特定的xml,他规定了一些标签的名称,结构与xml是 ...
- asctime_s asctime
asctime_s asctime // rand随机数.cpp : 此文件包含 "main" 函数.程序执行将在此处开始并结束. // #include "pch.h ...
- libco协程原理简要分析
此文简要分析一下libco协程的关键原理. 在分析前,先简单过一些协程的概念,以免有新手误读了此篇文章. 协程是用户态执行单元,它的创建,执行,上下文切换,挂起,销毁都是在用户态中完成,对linux系 ...
- Java 从Character和char的区别来学习自动拆箱装箱
本文结构 1.Character和char 的区别: 2.自动拆箱装箱 1.Character和char 的区别: Character是类,char基本数据类型. 在java中有三个类负责对字符的操作 ...
- 自己动手实现java断点/单步调试(一)
又是好长时间没有写博客了,今天我们就来谈一下java程序的断点调试.写这篇主题的主要原因是身边的公司或者个人都执着于做apaas平台,简单来说apaas平台就是一个零代码或者低代码的配置平台,通过配置 ...
- mysql 用户 登陆 权限相关
1. CREATE USER 'dog2'@'localhost' IDENTIFIED BY ''; 将"localhost"改为"%",表示在任何一台电脑上 ...