Description
神校XJ之学霸兮,Dzy皇考曰JC。 摄提贞于孟陬兮,惟庚寅Dzy以降。 纷Dzy既有此内美兮,又重之以修能。
遂降临于OI界,欲以神力而凌♂辱众生。 今Dzy有一魞歄图,其上有N座祭坛,又有M条膴蠁边。
时而Dzy狂WA而怒发冲冠,神力外溢,遂有K条膴蠁边灰飞烟灭。 而后俟其日A50题则又令其复原。(可视为立即复原)
然若有祭坛无法相互到达,Dzy之神力便会大减,于是欲知其是否连通。
Input
第一行N,M 接下来M行x,y:表示M条膴蠁边,依次编号 接下来一行Q 接下来Q行:
每行第一个数K而后K个编号c1~cK:表示K条边,编号为c1~cK 为了体现在线,K以及c1~cK均需异或之前回答为连通的个数
Output
对于每个询问输出:连通则为‘Connected’,不连通则为‘Disconnected’ (不加引号)
Sample Input
5 10
2 1
3 2
4 2
5 1
5 3
4 1
4 3
5 2
3 1
5 4
5
1 1
2 7 0 3
6 0 7 4 6
1 2 7
0 5 0 2 13
Sample Output
Connected
Connected
Connected
Connected
Disconnected
HINT
N≤100000 M≤500000 Q≤50000 1≤K≤15
数据保证没有重边与自环
Tip:请学会使用搜索引擎
题解
这题特别牛逼
你会发现K也被异或了,然后其实他后面的数的数量已经暴露了他异或后的值
所以我们是可以直接算出第i次询问之前的连通数。。
最后一次暴力搞就行了
然后有一个特别坑的地方,我的代码是过不去样例的2333..
因为输入的Q后有换行
但是别的都没有2333…
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<algorithm>
#include<cmath>
using namespace std;
struct node{
int x,y;}a[510000];
int fa[110000],n,m,Q,K,ANS,gt[510000];
int findfa(int x){
return fa[x]!=x?fa[x]=findfa(fa[x]):fa[x];}
char ch[21110000];
bool v[510000];
int main()
{scanf("%d%d",&n,&m);for(int i=1;i<=m;i++)scanf("%d%d",&a[i].x,&a[i].y);scanf("%d\n",&Q);for(int T=1;T<=Q;T++){gets(ch+1);int len=strlen(ch+1),sum=0;for(int i=1;i<=len;i++)if(ch[i]==' ')sum++;int x=0;for(int i=1;i<=len;i++){if(ch[i]!=' ')x=x*10+ch[i]-'0';else break;}gt[T]=x^sum;//T前面有几个联通了 }for(int i=2;i<=Q;i++){if(gt[i]-gt[i-1]==1)printf("Connected\n");else printf("Disconnected\n");}int K=0,u,len=strlen(ch+1);for(int i=1;i<=len;i++){if(ch[i]>='0' && ch[i]<='9')K=K*10+ch[i]-'0';else {K=K^gt[Q];u=i+1;break;}}memset(v,false,sizeof(v));for(int i=1;i<=K;i++){int x=0,j=u;while(ch[j]>='0' && ch[j]<='9')x=x*10+ch[j]-'0',j++;u=j+1;x^=gt[Q];v[x]=true;}int cnt=n;for(int i=1;i<=n;i++)fa[i]=i;for(int i=1;i<=m;i++)if(!v[i]){int p=findfa(a[i].x),q=findfa(a[i].y);if(p!=q){fa[p]=q;cnt--;}if(cnt==1)break;}if(cnt==1)printf("Connected\n");else printf("Disconnected\n");return 0;
}