Run ID | 作者 | 问题 | 语言 | 测评结果 | 分数 | 时间 | 内存 | 代码长度 | 提交时间 |
---|---|---|---|---|---|---|---|---|---|
52639 | LinkZelda | 子网 | C++ | 通过 | 100 | 527 MS | 3784 KB | 2552 | 2022-07-19 19:22:49 |
#include<cstdio> #include<algorithm> #include<ctype.h> #include<cstring> #include<iostream> #include<vector> #include<queue> #include<ctime> #include<cmath> #include<queue> #include<map> #include<set> #include<unordered_map> #include<stack> #define pr pair<int,int> #define eps 1e-8 #define db double using namespace std; inline int read() { int x=0,f=1; char ch=getchar(); while(!isdigit(ch)) { if(ch=='-')f=-1; ch=getchar(); } while(isdigit(ch)) { x=x*10+ch-'0'; ch=getchar(); } return x*f; } const int N=2000005; int head[N],to[N],nxt[N],cnt; void add(int u,int v) { to[++cnt]=v; nxt[cnt]=head[u]; head[u]=cnt; } int lk[20005],pre[20005],bin[20005]; int n,m,tot; int tag[20005],num[20005]; queue<int>Q; int anc(int x) { return bin[x]==x?x:bin[x]=anc(bin[x]); } void rev(int x) { if(!x) return; rev(lk[pre[x]]); lk[pre[x]]=x; lk[x]=pre[x]; } int LCA(int x,int y) { ++tot; while(1) { if(num[x=anc(x)]==tot) return x; else if(x) num[x]=tot; x=pre[lk[x]]; swap(x,y); } } void ins(int x,int y,int lca) { while(anc(x)!=lca) { pre[x]=y,y=lk[x]; bin[x]=bin[y]=lca;// 不能写成 bin[anc(x)]=bin[anc(y)]=anc(lca); if(tag[y]==2) tag[y]=1,Q.push(y); x=pre[y]; } } int work(int s) { fill(tag,tag+n+1,0); fill(pre,pre+n+1,0); for(int i=1; i<=n; i++) bin[i]=i; while(!Q.empty()) Q.pop(); Q.push(s); tag[s]=1; while(!Q.empty()) { int now=Q.front(); Q.pop(); for(int i=head[now]; i; i=nxt[i]) { int v=to[i]; if(tag[v]==1) { int lca=LCA(now,v); ins(now,v,lca); ins(v,now,lca); } else if(!tag[v]) { tag[v]=2; pre[v]=now; if(!lk[v]) return rev(v),1; else tag[lk[v]]=1,Q.push(lk[v]); } } } return 0; } int ans,nn; int main() { // freopen("P6113_4.in","r",stdin); // freopen("P6113_4.ans","w",stdout); n=nn=read(),m=read(); for(int i=1; i<=m; i++) { int k=read(); int x=++n,y=++n; add(x,y); add(y,x); lk[x]=y; lk[y]=x; ans++; while(k--) { int ovo=read(); add(x,ovo); add(ovo,x); add(y,ovo); add(ovo,y); } } for(int i=1; i<=n; i++) ans+=!lk[i]&&work(i); printf("%d\n",ans-m); // fclose(stdin); // fclose(stdout); return 0; }