标签: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