首页 > 其他分享 >Codeforces Round 847 (Div. 3) G.Tokens on Graph (构造)

Codeforces Round 847 (Div. 3) G.Tokens on Graph (构造)

时间:2023-04-27 11:11:09浏览次数:48  
标签:847 灰色 终点 int Graph Codeforces std 红色 YES

传送门

题目大意

  给定一个无向图,我们定义图中有四种点,一种是黑色的点表示终点,并且黑色的点始终是1号点,一种是红色的点,一种是灰色的点,最后一种就是没有颜色的点。

  游戏规则:我们必须移动任意一个灰色的点到相邻的点上,如果灰色的点移动到了红色的点上,那么我们可以移动其他灰色的点继续上述操作(不能移动自己),否则游戏结束。如果我们最终能使灰色的点到达终点,那么输出YES,如果不能使灰色的的点到达终点,输出NO。一下图为例:

  我们这么移动8->6,7->5,6->4, 5->6, 4->2, 6->4, 2->1游戏结束到达终点输出YES。

  输入一个整数T,表示有T组测试数据(1≤T≤1e4)。测试用例由一个空字符串分隔

  输入n和m表示有n个点m个边 (1≤n≤2e5 , 0≤m≤2e5),并且保证图一定联通,任何点之间都是可以到达的。

  输入p和b表示有p个黑色的点和b个红色的点。其中(1≤p≤n,0≤b≤n )。也就是说可能没有红色的点。

  输入p个两两不同的灰色的点,表示灰色的点所在的位置。

  输入b个红色的点,表示红色点所在的位置(灰色点可以和红色点重合,并且一个点上可以有多个灰色点,如果b为0则这一行为空)。

  输入m行u,v表示u和v之间有一条边。

  可以保证所有测试用例的n之和不超过2e5。同样地,保证所有输入数据集的m之和不超过2e5

解题思路:

  如果有灰色的点在终点直接输出YES,或者终点附近有灰色的点直接输出YES。

  我们发现一个性质,那就是如果一个灰色的点能走到红色的点,并且这个红色的点周围也有红色的点,那么我们就可以一直在这两个红色的点之间一直走下去。所以我们把红色的点分为两类:

  1.可以走无限步数的红色的点。

  2.只能走一步的红色的点。

  我们从终点出发找到所有能到达的灰色的点,并将这些点的编号和离终点的距离丢进一个vector<pair<int, int>> use;数组里面。

  如果use为空那么一定无解。

  我们把use内的第一个元素的编号定义为st,第一个元素到终点的距离定义为sum。我们从其他所有灰色点出发,如果这些灰色的点能走出第一种红色的点那么输出YES,如果这些灰色的点能走的第二种点的数量大于等于sum-1,那么也输出YES。但是我们第一个元素不一定就是能走到终点的点,因为我们可能第一个元素能走出第一种点,那么如果存在第二个元素也可以直接输出YES。

  

#include <bits/stdc++.h>

const int N = 2e5 + 10, M = N << 2;

int n, m;
typedef long long ll;
const int INF = 0x3f3f3f3f;
typedef std::pair<int, int> PII;

int h[N], ne[N << 1], e[N << 1], idx;

inline void add(int a, int b) {
	ne[idx] = h[a], e[idx] = b, h[a] = idx ++;
}

inline void slove() {
	std::cin >> n >> m;
	std::vector<bool> grey(n, 0), red(n, 0);//i号点是不是灰色点或者红色点
	idx = 0;
	for (int i = 0; i < n; i ++) h[i] = -1;
	int p, b;
	std::cin >> p >> b;
	std::vector<int> point;//存储所有灰色点编号

	for (int i = 1; i <= p; i ++) {
		int x;
		std::cin >> x;
		x --;
		grey[x] = true;//给灰色点打标记
		point.push_back(x);
	}
	
	for (int i = 1; i <= b; i ++) {
		int x;
		std::cin >> x;
		x --;
		red[x] = true;//给红色点打标记
	}
	
	while (m --) {
		int a, b;
		std::cin >> a >> b;
		a --, b --;
		add(a, b);
		add(b, a);
	}
	
	std::vector<bool> good(n, 0);//本身是红色周围也有红色,那么到达这个点可以一直走下去。
	
	for (int i = 0; i < n; i ++) {//找到本身是红色邻边也为红色的点
		if (red[i]) {
			bool f = false;
			for (int j = h[i]; ~j; j = ne[j]) {
				int k = e[j];

				if (red[k]) {
					f = true;
					break;
				}
			}

			if (f)	good[i] = true;
		}
	}

	
	if (grey[0]) {//如果灰色点在终点直接输出YES
		std::cout << "YES" << '\n';
		return ;
	}
	
	std::vector<PII> use;//记录能到达终点的灰色点的编号和到终点的距离
	int st = -1, sum = 0;//记录离终点最近的点的编号和距离
	auto bfs = [&]() -> void {
		std::queue<PII> q;
		std::vector<bool> vis(n);
		q.push({0, 0});
		vis[0] = true;
		while (!q.empty()) {
			PII u = q.front();
			q.pop();
			for (int i = h[u.first]; ~i; i = ne[i]) {
				int j = e[i];
				if (vis[j])	continue;
				if (grey[j]) {
					if (st == -1) {
						st = j;
						sum = u.second + 1; 
					}
					use.push_back({st, u.second + 1});
				}
				if (red[j]) {
					q.push({j, u.second + 1});
					vis[j] = true;
				}
			}
		}
	};
	
	bfs();
	if (st == -1) {//如果没有灰色点可以到达终点直接输出NO即可
		std::cout << "NO" << '\n';
		return ;
	}

	bool ok = false;//ok表示是否有一个灰色的可以无限走(即能走到good的点上)
	int step = 0;
	
	for (auto &u: point) {
		if (u != st) {//判断其他点是能走的步数。
			bool f = false;
			for (int i = h[u]; ~i; i = ne[i]) {
				int j = e[i];
				if (good[j]) {
					ok = true;
					break;
				}
				if (red[j]) f = true;
			}
			if (f)	step ++;
		} else {//如果离终点最近的点可以无限走,并且还有其他可以到达终点的点直接输出YES
			for (int i = h[u]; ~i; i = ne[i]) {
				int j = e[i];
				if (ok && use.size() > 1) {
					std::cout << "YES" << '\n';
					return ;
				}
			}
		}
		if (ok) break;
	}
	
	if (ok || sum == 1) std::cout << "YES" << '\n';
	else if (step >= sum - 1) std::cout << "YES" << '\n';
	else std::cout << "NO" << '\n';
}

int main(void) {
	std::ios::sync_with_stdio(false);
	std::cin.tie(0);
	std::cout.tie(0);
	
	int _ = 1;
	std::cin >> _;
	while (_ --) slove();
	
	return 0;
}

标签:847,灰色,终点,int,Graph,Codeforces,std,红色,YES
From: https://www.cnblogs.com/qdhys/p/17358235.html

相关文章

  • Codeforces Round 867 (Div. 3)
    A.TubeTubeFeed#include<bits/stdc++.h>usingnamespacestd;intmain(){intq;cin>>q;while(q--){intn,t,res=-1,id=-1;cin>>n>>t;vector<int>a(n+1),b(n+1);......
  • Educational Codeforces Round 147 (Rated for Div. 2)
    Preface补题这周比赛挺少,不过后面可能就很少有时间补以前的比赛了的说现在除了要做学校的集训专题外,还要刷一下蓝桥杯国赛的题,可以说是很忙碌了而且由于JAVA的期末考试要来了,为了熟悉下语法以后补题的时候前面的题目可能会用JAVA来写(其实我写的JAVA看起来和C++真没啥区别)A.......
  • spectral-graph-theory-in-GCN
    GCN中的谱图理论笔记Datetime:2023-04-26T09:36+08:00Categories:MachineLearningTags:GNN写毕设,发现自己没法绕过第一代GCN的谱图变换原理我知道啥是傅里叶变化,但是我感觉不到那种新奇,或许这就是无法感觉到数学的美吧。本文默认读者知道傅里叶变换,就数学分析/高等数......
  • Codeforces 1781G - Diverse Coloring(构造)
    vp时候想到大致思路了,但是死活调不对,赛后套取cf的数据调了好久才过/ll首先直觉告诉我们答案不会太大。稍微猜一猜可以猜出除了四个点的菊花之外答案都是\(n\bmod2\),下面我们来通过构造证明这件事情。首先,链的情况是trivial的,直接根据奇偶性间隔染色即可。如果不是链,那么......
  • Educational Codeforces Round 147(A~E)(补提记录)
    EducationalCodeforcesRound147(RatedforDiv.2)A:题意:每个问号都能被替换成0~9,求替换每个问号后所能的到的数的数量注:所得到的序列不能有前导0思路:先判断第一位是什么,作为特判,为0,则不能得到任何数输出0,为?则答案×9再依次枚举之后的每一个数,若为问号答案*10#include<io......
  • nginx-lua-fastdfs-GraphicsMagick整合
      无意发现了一个不错的分布式文件系统。fastdfs开源的分布式文件系统,此脚本利用nginxlua模块,动态生成图片缩略图,fastdfs只存一份原图。lua通过socket获取fastdfs的原图,并存放到本地,根据不同规则url,例如:_60x60.jpg、_80x80.jpg,类似淘宝图片url规则。利用gm命令生成本地缩略图......
  • Codeforces Round 867 (Div. 3)(A-C)
    A.TubeTubeFeed签到题思路往后走,每次减一,记录当前所能得到最大的bi完整代码#include<bits/stdc++.h>usingnamespacestd;#definelllonglonginlinellread(){lls=0;charg=getchar();while(g>'9'||g<'0')g=getchar();while(g&g......
  • Codeforces Round #459 (Div. 2) D. MADMAX DAG&&博弈
    Asweallknow,Maxisthebestvideogameplayeramongherfriends.Herfriendsweresojealousofhers,thattheycreatedanactualgamejusttoprovethatshe’snotthebestatgames.Thegameisplayedonadirectedacyclicgraph(aDAG)withnvertic......
  • Codeforces Round #306 (Div. 2) D. Regular Bridge 构造
    Anundirectedgraphiscalledk-regular,ifthedegreesofallitsverticesareequalk.Anedgeofaconnectedgraphiscalledabridge,ifafterremovingitthegraphisbeingsplitintotwoconnectedcomponents.Buildaconnectedundirectedk-regularg......
  • Codeforces Round #465 (Div. 2) D. Fafa and Ancient Alphabet 数学概率
    AncientEgyptiansareknowntohaveusedalargesetofsymbolstowriteonthewallsofthetemples.FafaandFifawenttooneofthetemplesandfoundtwonon-emptywordsS1andS2ofequallengthsonthewalloftemplewrittenonebelowtheother.Sinc......