题意:有一个有向图,有些点是煤,有些点是铁,但不会同时有铁和煤。现在我要从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 + 思维)题解的更多相关文章

  1. DFS/BFS+思维 HDOJ 5325 Crazy Bobo

    题目传送门 /* 题意:给一个树,节点上有权值,问最多能找出多少个点满足在树上是连通的并且按照权值排序后相邻的点 在树上的路径权值都小于这两个点 DFS/BFS+思维:按照权值的大小,从小的到大的连有 ...

  2. Gym 100971A Treasure Island BFS 思维题

    A - Treasure Island Time Limit:2000MS     Memory Limit:262144KB     64bit IO Format:%I64d & %I64 ...

  3. Gym - 101572D Distinctive Character bfs 思维

    题目传送门 题目大意: 给出n个01串,让你构造一个字符串,使这个字符串和这些字符串中相似程度最高 尽可能低.如果两个字符串对应位置相同,则相似程度加一. 思路: 每一个01串更改自己的一部分后,都可 ...

  4. Codeforces Gym101170I:Iron and Coal(建多幅图+多次BFS)***

    题目链接 题意 有n个点,其中有m个点是铁矿,k个点是煤,从1号点出发,你可以派一些士兵跑向不同的点,问占领至少一个铁矿和一个煤的时候,最少需要占领多少个点. 思路 建两幅图,其中一幅是正向边,一幅是 ...

  5. Codeforces Gym 100187E E. Two Labyrinths bfs

    E. Two Labyrinths Time Limit: 20 Sec Memory Limit: 256 MB 题目连接 http://codeforces.com/gym/100187/prob ...

  6. Gym - 100187E E - Two Labyrinths —— bfs

    题目链接:http://codeforces.com/gym/100187/problem/E 题解:一开始做的时候是将两幅图合并,然后直接bfs看是否能到达终点.但这种做法的错的,因为走出来的路对于 ...

  7. ACM: Gym 101047E Escape from Ayutthaya - BFS

    Gym 101047E Escape from Ayutthaya Time Limit:2000MS     Memory Limit:65536KB     64bit IO Format:%I6 ...

  8. Gym 101617J Treasure Map(bfs暴力)

    http://codeforces.com/gym/101617/attachments 题意:给出一个图,每个顶点代表一个金矿,每个金矿有g和d两个值,g代表金矿初始的金子量,d是该金矿每天的金子量 ...

  9. 逃离迷宫(BFS)题解

    Problem Description 给定一个m × n (m行, n列)的迷宫,迷宫中有两个位置,gloria想从迷宫的一个位置走到另外一个位置,当然迷宫中有些地方是空地,gloria可以穿越,有 ...

随机推荐

  1. 【Python】中国有哪些同名的省市县?

    这道题适合写个脚本来解. 首先从百度地图API下载一份行政区划数据. 开发资源 | 百度地图API SDK 然后做一个简单的数据统计就可以啦~ 行政区划同一级同名的: import pandas as ...

  2. dotnet cli 5.0 新特性——dotnet tool search

    dotnet cli 5.0 新特性--dotnet tool search Intro .NET 5.0 SDK 的发布,给 dotnet cli 引入了一个新的特性,dotnet tool sea ...

  3. LVS负载均衡理论以及算法概要

    一. LVS简介 LVS是Linux Virtual Server的简称,也就是Linux虚拟服务器, 由章文嵩博士发起的自由软件项目,它的官方站点是www.linuxvirtualserver.or ...

  4. 有状态 无状态 stateful stateless monolithic architecture microservice architecture 单体架构

    为什么游戏公司的server不愿意微服务化? - 知乎 https://www.zhihu.com/question/359630395 我大概说了,方便测试,方便维护,方便升级,服务之间松耦合,可多 ...

  5. 洛谷 P1401 城市

    写在前面 今天来水主题库里的有水分的紫题,随便一翻竟然找到宝了. 小清新二分 + 网络流. 算法思路 考虑到题目中限制的是最大边权,要求最大边权最小,那么很容易想到二分答案. 单调性的证明:最大边权是 ...

  6. C#Process调用外部程序

    前言 使用C#调用外部程序,一种是通过Process类,一种是通过命令行,本文主要说一下使用C#中的Process类调用外部程序的方式. 过程: 1. 创建Process对象 2. 配置启动选项(输入 ...

  7. 玩转IDEA项目结构Project Structure,打Jar包、模块/依赖管理全搞定

    前言 你好,我是A哥(YourBatman). 如何给Module模块单独增加依赖? 如何知道哪些Module模块用了Spring框架,哪些是web工程? IDEA如何打Jar包?打War包? 熟练的 ...

  8. Linux 调整系统时间偏差

    在使用Linux系统部署项目,有时会出现时间跟当前时间不一致的情况,这个时候需要做些调整: 1.首先删除之前设置的时区 rm -rf /etc/localtime 2.创建上海时区 ln -s /us ...

  9. zabbix监控设备结果异常问题

    1.现象描述 paloalto防火墙升级后发现zabbix监控其CPU.风扇等硬件信息和端口流量数据错误. 2.现象分析 由于zabbix并没有做过任何调整,防火墙也只是升级.根据现象并不好排查.但是 ...

  10. SSL与HTTPS协议

    1.SSL 1.1 什么是SSL SSL(Secure Sockets Layer 安全套接层),及其继任者传输层安全(Transport Layer Security,TLS)是为网络通信提供安全及 ...