首页 > 其他 > 详细

Codeforces891C. Envy

时间:2018-03-24 18:12:14      阅读:214      评论:0      收藏:0      [点我收藏+]

$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

原文:https://www.cnblogs.com/Blue233333/p/8640642.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!