ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

[bzoj3569]DZY Loves Chinese II

2021-07-17 20:01:12  阅读:211  来源: 互联网

标签:连通 int complement II edge DZY 非树边 bzoj3569 sum


若原图不连通,显然答案都是"Disconnected",不妨假设原图连通

任求一棵生成树,对每条非树边随机一个权值,并将树边的权值为所有"包含"其的非树边("包含"指树边在非树边两端点生成树的路径上),那么每一条边即都有一个边权

下面,只需要判定删除的边权是否存在非空子集异或和为0即可(存在即不连通)

具体实现上,随机值范围在long long中即可,求树边的权值可以差分,判定使用线性基即可

时间复杂度为$o(m+qk\log V)$(其中$V$为随机值范围),可以通过

关于其的正确性,证明来自于这篇blog,摘抄如下——

必要性:

若删掉边后的图不连通,任选其中一个极大连通块$S$,考虑$S$和$\complement_{V}S$(其中$V$为原图点集)之间的边,显然存在(指非空)且都被删除,下面只需要说明这些边异或和为0

关于这个,考虑所有非树边(包括不在$S$和$\complement_{V}S$之间的边),对其分类讨论:

1.在$S$或$\complement_{V}S$内部,将其两端点生成树的路径上$S$和$\complement_{V}S$之间的边取出,由于每一条这样的边都会改变其所属的集合,而最终其所属集合没有变化,那么必然是偶数条,即其贡献为0

2.在$S$和$\complement_{V}S$之间的边,同理取出这些边,必然是奇数条,即其贡献也为0

综上,即得证

充分性:

考虑一个异或和为0的非空边集,将其中的树边先删除,即将生成树划分为若干个连通块(不考虑非树边)

对这些连通块黑白染色,要求使得任意一条被删除的树边两端点所属连通块不同色

此时,考虑一条未被删除的非树边,在忽略随机的值很特殊的情况下,可以认为其两端点生成树的路径上在此边集中的边为偶数条,也即其所连结的两个连通块同色

由此,不难发现不同色的点对之间一定没有(未被删除的)边,也即这两个集合不连通,同时由于边集非空,即总存在树边,那么两个集合都非空

综上,即得证

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 #define N 100005
 4 #define M 500005
 5 #define L 63
 6 #define ll long long
 7 struct Edge{
 8     int nex,to;
 9 }edge[M<<1];
10 int E,n,m,q,x,y,ans,head[N],dfn[N];
11 ll z,a[L],val[M],sum[N];
12 void add(int x,int y){
13     edge[E].nex=head[x];
14     edge[E].to=y;
15     head[x]=E++;
16 }
17 void dfs1(int k,int fa){
18     dfn[k]=++dfn[0];
19     for(int i=head[k];i!=-1;i=edge[i].nex)
20         if (edge[i].to!=fa){
21             if (!dfn[edge[i].to])dfs1(edge[i].to,k);
22             else{
23                 if (dfn[k]<dfn[edge[i].to])continue;
24                 for(int j=0;j<L;j++)val[(i>>1)]=(val[(i>>1)]<<1)+rand()%2;
25                 sum[k]^=val[(i>>1)],sum[edge[i].to]^=val[(i>>1)];
26             }
27         }
28 }
29 void dfs2(int k,int fa){
30     dfn[k]=++dfn[0];
31     for(int i=head[k];i!=-1;i=edge[i].nex)
32         if (!dfn[edge[i].to]){
33             dfs2(edge[i].to,k);
34             val[(i>>1)]=sum[edge[i].to];
35             sum[k]^=sum[edge[i].to];
36         }
37 }
38 int main(){
39     scanf("%d%d",&n,&m);
40     memset(head,-1,sizeof(head));
41     for(int i=1;i<=m;i++){
42         scanf("%d%d",&x,&y);
43         add(x,y);
44         add(y,x);
45     }
46     dfs1(1,0);
47     scanf("%d",&q);
48     for(int i=1;i<=n;i++)
49         if (!dfn[i]){
50             while (q--)printf("Disconnected\n");
51             return 0;
52         }
53     memset(dfn,0,sizeof(dfn));
54     dfs2(1,0);
55     while (q--){
56         scanf("%d",&x);
57         memset(a,0,sizeof(a));
58         int tot=0;
59         for(int i=1;i<=x;i++){
60             scanf("%d",&y);
61             z=val[(y^ans)-1];
62             for(int j=L-1;j>=0;j--)
63                 if (z&(1LL<<j)){
64                     if (!a[j]){
65                         a[j]=z;
66                         tot++;
67                     }
68                     z^=a[j];
69                 }
70         }
71         if (tot<x)printf("Disconnected\n");
72         else{
73             printf("Connected\n");
74             ans++;
75         }
76     }
77 }
View Code

 

标签:连通,int,complement,II,edge,DZY,非树边,bzoj3569,sum
来源: https://www.cnblogs.com/PYWBKTDA/p/15024702.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有