Codeforces891C. Envy

Posted Blue233333

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Codeforces891C. Envy相关的知识,希望对你有一定的参考价值。

$n \leq 5e5$,$m \leq 5e5$的无向边权图,$q \leq 5e5$个询问,每次问一系列边是否能同时存在于某棵最小生成树上。

一条边在最小生成树上,当比他小的边都加入后,加入他会使连通块数-1,也就是他两端的点在加入比他小的所有边后仍不在一起。

于是乎把所有询问的所有边排序,每次处理一个询问的一种边,新开一个并查集看看把这个询问的边加进去之后会不会有一条边是废的(没使连通块数-1,也就是两端点的并查集父亲相同)。

技术分享图片
 1 //#include<iostream>
 2 #include<cstring>
 3 #include<cstdlib>
 4 #include<cstdio>
 5 #include<vector>
 6 //#include<queue>
 7 //#include<time.h>
 8 //#include<complex>
 9 #include<algorithm>
10 #include<stdlib.h>
11 using namespace std;
12 
13 int n,m,lq;
14 #define maxn 500011
15 struct Edge{int from,to,v;}edge[maxn];
16 int ufs[maxn],vis[maxn],ufsb[maxn];
17 int find(int x) {return ufs[x]==x?x:(ufs[x]=find(ufs[x]));}
18 int findb(int Time,int x) {return vis[x]==Time?(ufsb[x]==x?x:(ufsb[x]=findb(Time,ufsb[x]))):(vis[x]=Time,(ufsb[x]=find(x)));}
19 
20 bool ans[maxn];
21 struct vnode{int id,e;};
22 vector<vnode> v[maxn],ve[maxn];
23 
24 int main()
25 {
26     scanf("%d%d",&n,&m); int maxv=0;
27     for (int i=1,x,y,val;i<=m;i++) scanf("%d%d%d",&x,&y,&val),maxv=max(maxv,val),
28     edge[i]=(Edge){x,y,val},ve[val].push_back((vnode){x,y});
29     
30     scanf("%d",&lq);
31     for (int i=1,x,y;i<=lq;i++)
32     {
33         scanf("%d",&x);
34         while (x--) scanf("%d",&y),v[edge[y].v].push_back((vnode){i,y});
35     }
36     
37     for (int i=1;i<=n;i++) ufs[i]=i;
38     int Time=0;
39     for (int i=1;i<=maxv;i++)
40     {
41         for (int j=0,last=0,to=v[i].size();j<to;j++)
42         {
43             int id=v[i][j].id,x=edge[v[i][j].e].from,y=edge[v[i][j].e].to;
44             if (last!=id) ++Time;
45             if (vis[x]!=Time) vis[x]=Time,ufsb[x]=find(x);
46             if (vis[y]!=Time) vis[y]=Time,ufsb[y]=find(y);
47             if (findb(Time,x)==findb(Time,y)) ans[id]=1;
48             ufsb[ufsb[x]]=ufsb[y];
49             last=id;
50         }
51         for (int j=0,to=ve[i].size();j<to;j++)
52         {
53             int x=find(ve[i][j].id),y=find(ve[i][j].e);
54             if (x!=y) ufs[x]=y;
55         }
56     }
57     for (int i=1;i<=lq;i++) puts(ans[i]?"NO":"YES");
58     return 0;
59 }
View Code

 

以上是关于Codeforces891C. Envy的主要内容,如果未能解决你的问题,请参考以下文章

CF891C Envy

CF891C Envy

「CF891C」Envy

[题解] [CF891C] Envy

[CF891C] Envy - Kruskal,并查集

CF 891C Envy 最小生成树+可撤销并查集