这题什么情况。。。。。直接暴力加标记,复杂度o(n)啊。。。明显能过啊。。。明显是除了签到最简单的一道。。。。居然过这么少人。。。估计很多人看到merge和split以为是什么数据结构。。
#include<iostream> #include<cstdio> #include<cstring> #include<cstdlib> #include<algorithm> #include<vector> #include<map> #define REP(i,a,b) for(int i=a;i<=b;i++) #define MS0(a) memset(a,0,sizeof(a)) #define key_val ch[ch[rt[i]][1]][0] #define lson l,m,rt<<1 #define rson m+1,r,rt<<1|1 using namespace std; typedef long long ll; const int maxn=1000100; const int INF=1e9+10; struct Edge { int u,v; friend bool operator<(Edge A,Edge B) { return A.u==B.u?A.v<B.v:A.u<B.u; } };Edge e[maxn];int m; vector<int> G[maxn]; int un,vn; map<int,int> id,id2; bool vis[maxn]; int deg[maxn]; void dfs(int u) { if(vis[u]) return; vis[u]=1; for(int i=0;i<G[u].size();i++){ dfs(G[u][i]); } } int main() { #ifndef ONLINE_JUDGE freopen("in.txt","r",stdin); #endif int T;cin>>T; REP(casen,1,T){ scanf("%d",&m); REP(i,1,m) scanf("%d%d",&e[i].u,&e[i].v),e[i].u++,e[i].v++; sort(e+1,e+m+1);int tm=m;m=1; REP(i,2,tm) if(e[i].u!=e[i-1].u||e[i].v!=e[i-1].v) e[++m]=e[i]; id.clear();un=0; REP(i,1,m){ if(id[e[i].u]) continue; id[e[i].u]=++un; } vn=un; id2.clear();vn=un; REP(i,1,m){ if(id2[e[i].v]) continue; id2[e[i].v]=++vn; } REP(i,1,vn) G[i].clear();MS0(deg); REP(i,1,m){ e[i].u=id[e[i].u]; e[i].v=id2[e[i].v]; G[e[i].u].push_back(e[i].v); G[e[i].v].push_back(e[i].u); deg[e[i].u]++; deg[e[i].v]++; } int A=0,B=0,C=0;/// 1-n n-1 1-1 MS0(vis); int v; //cout<<"un="<<un<<" vn="<<vn<<endl; //REP(i,1,vn) cout<<deg[i]<<" ";cout<<endl; REP(i,1,un){ if(vis[i]) continue; if(deg[i]==1){ v=G[i][0]; if(deg[v]==1) C++; else dfs(i); } else if(deg[i]>1){ int tag=1; for(int j=0;j<G[i].size();j++){ v=G[i][j]; if(deg[v]!=1){ tag=0;break; } } if(tag==0) dfs(i); else A++; } } MS0(vis); REP(i,un+1,vn){ if(vis[i]) continue; if(deg[i]==1){ v=G[i][0]; if(deg[v]!=1) dfs(i); } else if(deg[i]>1){ int tag=1; for(int j=0;j<G[i].size();j++){ v=G[i][j]; if(deg[v]!=1){ tag=0;break; } } if(tag==0) dfs(i); else B++; } } printf("Case #%d: %d %d %d\n",casen,A,B,C); } return 0; }