题目分析
看了这道题的题目,感觉好难啊,不可做啊,那么我们就要找一些特殊的性质。注意到:
每行第一个数 K 而后 K 个编号 c1~cK:表示 K 条边,编号为 c1~cK
为了体现在线,K 以及 c1~cK 均需异或之前回答为连通的个数
诶……
所以,把一行读进来,查看这一行有多少个数,从而得到之前回答为连通的个数,然后就获得了上一个询问的答案。对于最后一个询问,我们直接用并查集维护一下即可。
代码
#include<bits/stdc++.h>
using namespace std;
#define RI register int
struct edges{int x,y;}e[500005];
char s[1005];
int n,m,q,blk,f[100005],ans[100005],v[500005];
int find(int x) {return f[x]==x?x:f[x]=find(f[x]);}
int main()
{
int k,js;
scanf("%d%d",&n,&m);
for(RI i=1;i<=m;++i) scanf("%d%d",&e[i].x,&e[i].y);
scanf("%d",&q);
for(RI i=1;i<=q;++i) {
scanf("%d",&k),gets(s+1),js=0;
int len=strlen(s+1);
for(RI j=1;j<=len;++j)
if(isdigit(s[j])&&!isdigit(s[j+1])) ++js;
ans[i]=js^k;
}
for(RI i=1;i<q;++i)
if(ans[i+1]==ans[i]) puts("Disconnected");
else puts("Connected");
k=0,s[0]='a';
int len=strlen(s+1);
for(RI i=1;i<=len;++i) {
if(isdigit(s[i])) k=k*10+s[i]-'0';
else if(isdigit(s[i-1])) v[k^ans[q]]=1,k=0;
}
v[k^ans[q]]=1;
blk=n;for(RI i=1;i<=n;++i) f[i]=i;
for(RI i=1;i<=m;++i)
if(!v[i]) {
int r1=find(e[i].x),r2=find(e[i].y);
if(r1!=r2) --blk,f[r1]=r2;
}
if(blk==1) puts("Connected");
else puts("Disconnected");
return 0;
}
1 条评论
konnyakuxzy · 2018年3月30日 8:33 下午
Orz
还有这种操作
赶紧膜 Orz%%%%%