codeforces 并查集_codeforces 892E 可撤销并查集

https://codeforces.com/problemset/problem/892/E

把询问离线,分步回答.

#include

#define ll long long

#define rep(ii,a,b) for(int ii=a;ii<=b;++ii)

#define per(ii,a,b) for(int ii=b;ii>=a;--ii)

#define forn(i,x,g,e) for(int i=g[x];i;i=e[i].next)

#define IO ios::sync_with_stdio(false);cin.tie(0);cout.tie(0)

#define ull unsigned long long

#define fi first

#define se second

#define mp make_pair

#define pii pair

#define all(x) x.begin(),x.end()

#define show(x) cout<

#define show2(x,y) cout<

#define show3(x,y,z) cout<

#define show4(w,x,y,z) cout<

#define show5(v,w,x,y,z) cout<

#define showa(x,a,b) cout<

using namespace std;//head

const int maxn=1e6+10,maxm=2e6+10;

const ll INF=0x3f3f3f3f,mod=1e9+7;

int casn,n,m,k;

class ufs{public:

int fa[maxn],sz[maxn];

stack stk;

void init(int tot){

rep(i,1,tot) fa[i]=i,sz[i]=1;

}

int find(int now){

if(fa[now]==now) return now;

return find(fa[now]);

}

bool unite(int a,int b){

a=find(a),b=find(b);

if(a==b)return 0;

if(sz[a]

else fa[b]=a,sz[a]+=sz[b],stk.push(make_pair(b,a));

return 1;

}

void undo(){

if(!stk.empty()){

auto now=stk.top();

stk.pop();

fa[now.fi]=now.fi;

sz[now.se]-=sz[now.fi];

}

}

}dsu;

struct node{int id,from,to,cost;}e[maxn];

vectora[maxn];

bool cmp(int a,int b){return e[a].cost

vector b[maxn],q[maxn];

int ans[maxn];

bool check(int id,int from,int to){

bool res=1;

int sum=0;

rep(i,from,to){

if(dsu.unite(e[q[id][i]].from,e[q[id][i]].to)) ++sum;

else res=0;

}

rep(i,1,sum) dsu.undo();

return res;

}

int main() {IO;

cin>>n>>m;

rep(i,1,m) {

cin>>e[i].from>>e[i].to>>e[i].cost;

b[e[i].cost].push_back(i);

}

cin>>k;

rep(i,1,k){

int sz;cin>>sz;

rep(_,1,sz){

int x;cin>>x;

q[i].push_back(x);

}

sort(all(q[i]),cmp);

int from=0;

rep(j,1,sz-1)

if(e[q[i][j]].cost!=e[q[i][j-1]].cost){

a[e[q[i][j-1]].cost].push_back({i,from,j-1,0});

from=j;

}

a[e[q[i][sz-1]].cost].push_back({i,from,sz-1,0});

}

dsu.init(n);

rep(i,1,maxn-5){

for(node j:a[i])

if(!check(j.id,j.from,j.to))

ans[j.id]=1;

for(int j:b[i])

dsu.unite(e[j].from,e[j].to);

}

rep(i,1,k) if(ans[i])cout<

";

else cout<

";

return 0;

}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值