码迷,mamicode.com
首页 > 其他好文 > 详细

Codeforces Round #446 (Div. 1) C - Envy

时间:2020-07-10 21:17:46      阅读:57      评论:0      收藏:0      [点我收藏+]

标签:using   for   stream   应该   queue   height   pop   int   div   

由krus求MST可以知道,我们将边集合按照权值大小排序,从小到大贪心的取,其中可以发现,如果权值=x的边,被选取,那么所有权值等于=x的边对应的点应该全部在当前构建的MST中。即,权值相等的边集,在构建MST的过程中,对应点集保持一致。
所以我们这道题目按照权值sort一遍,然后再离线保存下来查询的边,将查询的边也按照边权排序。然后每一次加入查询的边,先把小于当前查询的边的权值插入,然后再插入询问的边,最后恢复并查集到之前的状态即可。

#include<iostream>
#include<cstring>
#include<algorithm>
#include<cmath>
#include<cstdlib>
#include<climits>
#include<stack>
#include<vector>
#include<queue>
#include<set>
#include<bitset>
#include<map>
//#include<regex>
#include<cstdio>
#include <iomanip>
#pragma GCC optimize(2)
#define up(i,a,b)  for(int i=a;i<b;i++)
#define dw(i,a,b)  for(int i=a;i>b;i--)
#define upd(i,a,b) for(int i=a;i<=b;i++)
#define dwd(i,a,b) for(int i=a;i>=b;i--)
//#define local
typedef long long ll;
typedef unsigned long long ull;
const double esp = 1e-6;
const double pi = acos(-1.0);
const int INF = 0x3f3f3f3f;
const int inf = 1e9;
using namespace std;
ll read()
{
	char ch = getchar(); ll x = 0, f = 1;
	while (ch<‘0‘ || ch>‘9‘) { if (ch == ‘-‘)f = -1; ch = getchar(); }
	while (ch >= ‘0‘ && ch <= ‘9‘) { x = x * 10 + ch - ‘0‘; ch = getchar(); }
	return x * f;
}
typedef pair<int, int> pir;
#define lson l,mid,root<<1
#define rson mid+1,r,root<<1|1
#define lrt root<<1
#define rrt root<<1|1
const int N = 5e5 + 10;
int n, m, q;
vector<pir>vec[N], f[N];
pir a[N];
int val[N];
int ans[N];
struct node {
	int pos, to, h;
};
struct bcj {
	int par[N], height[N];
	stack<node>st;
	void init()
	{
		upd(i, 0, n)par[i] = i, height[i] = 1;
	}
	int find(int x)
	{
		return x == par[x] ? x : find(par[x]);
	}
	bool merge(int x,int y)
	{
		x = find(x); y = find(y);
		if (x == y)return 0;
		if (height[x] < height[y])swap(x, y);
		st.push(node{ y,x,height[y] });
		par[y] = x;
		height[x] += height[y];
		return 1;
	}
	void del()
	{
		node temp = st.top();
		par[temp.pos] = temp.pos;
		height[temp.to] -= temp.h;
		st.pop();
	}
}dsu;
int main()
{
	n = read(), m = read();
	int u, v, w, k;
	int mx = 0;
	upd(i, 1, m)
	{
		u = read(), v = read(), w = read();
		mx = max(mx, w);
		vec[w].push_back(make_pair(u, v));
		val[i] = w;
		a[i] = make_pair(u, v);
	}
	dsu.init();
	q = read();
	int ident = 0;
	while (q--)
	{
		k = read();
		++ident;
		ans[ident] = 1;
		while (k--)
		{
			u = read();
			f[val[u]].push_back(make_pair(u, ident));
		}
	}
	upd(i, 0, mx)
	{
		if (vec[i].empty())continue;
		if (f[i].size())
		{
			for (int j = 0, ii = 0; ii < f[i].size();)
			{
				int len = 0;
				while (j < f[i].size() && f[i][j].second == f[i][ii].second)
				{
					int fi = f[i][j].first;
					int fg = dsu.merge(a[fi].first, a[fi].second);
					ans[f[i][j].second] &= fg;
					if (fg)len++;
					j++;
				}
				while (len--)dsu.del();
				ii = j;
			}
		}
		for (auto k : vec[i])
		{
			dsu.merge(k.first, k.second);
		}
	}
	upd(i, 1, ident)
	{
		printf("%s\n", ans[i] ? "YES" : "NO");
	}
	return 0;
}

Codeforces Round #446 (Div. 1) C - Envy

标签:using   for   stream   应该   queue   height   pop   int   div   

原文地址:https://www.cnblogs.com/LORDXX/p/13280870.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!