您的位置:首页 > 其它

BZOJ3569: DZY Loves Chinese II

2016-04-12 21:02 411 查看

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
为了体现在线,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

3 7 0 3

4 0 7 4 6

2 2 7

4 5 0 2 13

Sample Output

Connected

Connected

Connected

Connected

Disconnected

HINT

N≤100000 M≤500000 Q≤50000 1≤K≤15

数据保证没有重边与自环

Tip:请学会使用搜索引擎

很厉害的思路,先随便找出一棵生成树,然后对非树边随便赋权值,对于树边权值赋为所有覆盖它的非树边的权值异或和。
那么询问时高斯消元一下判断是否有异或为0的子集,如果有就认为整张图不再连通。
竟然被卡了两次随机种子。。。

#include<cstdio>
#include<cctype>
#include<queue>
#include<cstring>
#include<algorithm>
#define rep(i,s,t) for(int i=s;i<=t;i++)
#define dwn(i,s,t) for(int i=s;i>=t;i--)
#define ren for(int i=first[x];i;i=edges[i].next)
using namespace std;
const int BufferSize=1<<16;
char buffer[BufferSize],*head,*tail;
inline char Getchar() {
if(head==tail) {
int l=fread(buffer,1,BufferSize,stdin);
tail=(head=buffer)+l;
}
return *head++;
}
inline int read() {
int x=0,f=1;char c=Getchar();
for(;!isdigit(c);c=Getchar()) if(c=='-') f=-1;
for(;isdigit(c);c=Getchar()) x=x*10+c-'0';
return x*f;
}
const int maxn=100010;
const int maxm=200010;
struct Edge {int to,next;}edges[maxm<<1];
int n,m,e=1,clo,f[maxn],vis[maxn],A[maxm],first[maxn];
void AddEdge(int u,int v) {
edges[++e]=(Edge){v,first[u]};first[u]=e;
edges[++e]=(Edge){u,first[v]};first[v]=e;
}
void dfs(int x,int fa) {
vis[x]=++clo;
ren {
Edge& e=edges[i];
if(fa==e.to) continue;
if(!vis[e.to]) {
dfs(e.to,x);
A[i>>1]=f[e.to];
f[x]^=f[e.to];
}
else if(vis[x]>vis[e.to]) {
A[i>>1]=rand()+1;
f[x]^=A[i>>1];
f[e.to]^=A[i>>1];
}
}
}
int S[25],N;
int gauss() {
int i,k=0;
dwn(j,30,0) {
for(i=k+1;i<=N;i++) if(S[i]>>j&1) break;
if(i==N+1) continue;
swap(S[++k],S[i]);
for(i=1;i<=N;i++) if(i!=k&&(S[i]>>j&1)) S[i]^=S[k];
}
return S
>0;
}
int main() {
srand(52501);
n=read();m=read();
rep(i,1,m) AddEdge(read(),read());
dfs(1,-1);
dwn(T,read(),1) {
N=read();
rep(i,1,N) S[i]=A[read()];
int ans=gauss();
puts(ans?"Connected":"Disconnected");
}
return 0;
}


  
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: