P17175 「MSOI R1」折磨 题解

P17175 「MSOI R1」折磨 题解

题目见 [P17175 「MSOI R1」折磨 - 洛谷]

很水的一道题(毕竟基础赛)

几个核心词:网络 扩散 屏蔽

基础思想:

考虑Flood Fill思想 设立一个\(vis\)数组 对所有满足\(arr[i] \leq val(发出去猫条的价值)\)的i进行染色(使得\(vis[i] = 1\))

最后都fill完了就以我们可怜的小猫为中心遍历其邻居看看有几个被感染上的直接\(ans++\)

注意事项:

为了保证严谨,我们在跑算法之前应对\(users\)数组按其发布的瓜条价值从高到低排列,但注意到题目中保证可以证明看到瓜条的顺序并不会影响最终结果。

但是去掉排序则只能拿到83pts 为什么呢?

代码如下:

#include<bits/stdc++.h>
#define int long long
#define endl "\n"
using namespace std;
inline int read(){
	int x = 0; bool f = 1; char c = getchar();
	for(; !isdigit(c); c = getchar()) if(c == '-') f = 0;
	for(; isdigit(c); c = getchar()) x = (x << 1) + (x << 3) + (c ^ 48);
	return f ? x : -x;
}
const int N = 2e5 + 10;
int n, e1, m, a, arr[N], users[N], vis[N];
vector<int> e[N];
inline void dfs(int node, int val){
	if(vis[node]){
		return;
	}//访问过了直接回去
	vis[node] = 1;//染色
	for(const auto o : e[node]){
		if(o == a){//我们的主角不要染
			continue;
		}
		if(arr[o] <= val){//满足条件
			arr[o] = val;
			dfs(o, arr[o]);
		}
	}
}
main(){
	n = read(), e1 = read(), m = read(), a = read();
	for(int i = 1; i <= n; ++i){
		arr[i] = read();
	}
	for(int i = 1, aa, bb; i <= e1; ++i){
		aa = read(), bb = read();
		e[aa].push_back(bb);
		e[bb].push_back(aa);
	}
	for(int i = 1; i <= m; ++i){
		users[i] = read();
	}
	int ans = 0;
	sort(users + 1, users + 1 + m, [&](int xx, int yy){return arr[xx] > arr[yy]; });
	for(int i = 1; i <= m; ++i){
		dfs(users[i], arr[users[i]]);
	}
	for(const auto o1 : e[a]){
		if(vis[o1]){
			ans++;
		}
	}
	cout << ans << endl;
	return 0;
}

递交记录

posted @ 2026-08-02 22:58  fl0ppy-  阅读(3)  评论(0)    收藏  举报