本来以为是tarjan缩点……但是64MB的空间根本不足以存下原图和缩点后的新图。所以呢……并查集= =
orz hzwer
MLE的tarjan:
1 /************************************************************** 2 Problem: 1529 3 User: Tunix 4 Language: C++ 5 Result: Memory_Limit_Exceed 6 ****************************************************************/ 7 8 //BZOJ 1529 9 #include<cstdio> 10 #include<cstring> 11 #include<cstdlib> 12 #include<iostream> 13 #include<algorithm> 14 #define rep(i,n) for(int i=0;i<n;++i) 15 #define F(i,j,n) for(int i=j;i<=n;++i) 16 #define D(i,j,n) for(int i=j;i>=n;--i) 17 using namespace std; 18 const int N=1000086; 19 20 void read(int &v){ 21 v=0;int sign=1; char ch=getchar(); 22 while(ch<‘0‘ || ch>‘9‘) {if (ch==‘-‘) sign=-1; ch=getchar();} 23 while(ch>=‘0‘&&ch<=‘9‘){v=v*10+ch-‘0‘; ch=getchar();} 24 v*=sign; 25 } 26 /********************tamplate*******************/ 27 int dfn[N],low[N],dfs_clock,SCC=0,belong[N],n; 28 int head[N],to[N],next[N],cnt; 29 void ins(int x,int y){ 30 to[++cnt]=y; next[cnt]=head[x]; head[x]=cnt; 31 } 32 int t[N],ne[N],h[N]; 33 void add(int x,int y){ 34 t[++cnt]=y; ne[cnt]=h[x]; h[x]=cnt; 35 } 36 bool inst[N]; 37 int st[N],top=0; 38 void tarjan(int x){ 39 int y; 40 dfn[x]=low[x]=++dfs_clock; 41 st[top++]=x; 42 inst[x]=1; 43 for(int i=head[x];i;i=next[i]){ 44 y=to[i]; 45 if (!dfn[y]){ 46 tarjan(y); 47 low[x]=min(low[x],low[y]); 48 } 49 else if (inst[y]) low[x]=min(low[x],dfn[y]); 50 } 51 if (dfn[x]==low[x]){ 52 ++SCC; 53 for(y=0;y!=x;){ 54 y=st[--top]; 55 inst[y]=0; 56 belong[y]=SCC; 57 } 58 } 59 } 60 int in[N]; 61 void rebuild(){ 62 F(x,1,n) 63 for(int i=head[x];i;i=next[i]) 64 if (belong[x]!=belong[to[i]]){ 65 add(belong[x],belong[to[i]]); 66 in[belong[to[i]]]++; 67 } 68 } 69 /***********************************************/ 70 71 int main(){ 72 #ifndef ONLINE_JUDGE 73 freopen("1529.in","r",stdin); 74 #endif 75 read(n); 76 int x; 77 F(i,1,n){ 78 read(x); 79 ins(x,i); 80 } 81 F(i,1,n) if (!dfn[i]) tarjan(i); 82 rebuild(); 83 int ans=0; 84 F(i,1,SCC) if(in[i]==0) ans++; 85 printf("%d\n",ans); 86 return 0; 87 }
并查集:
1 /************************************************************** 2 Problem: 1529 3 User: Tunix 4 Language: C++ 5 Result: Accepted 6 Time:908 ms 7 Memory:4712 kb 8 ****************************************************************/ 9 10 //BZOJ 1529 11 #include<cstdio> 12 #define rep(i,n) for(int i=0;i<n;++i) 13 #define F(i,j,n) for(int i=j;i<=n;++i) 14 #define D(i,j,n) for(int i=j;i>=n;--i) 15 using namespace std; 16 const int N=1000086; 17 18 void read(int &v){ 19 v=0;int sign=1; char ch=getchar(); 20 while(ch<‘0‘ || ch>‘9‘) {if (ch==‘-‘) sign=-1; ch=getchar();} 21 while(ch>=‘0‘&&ch<=‘9‘){v=v*10+ch-‘0‘; ch=getchar();} 22 v*=sign; 23 } 24 int fa[N],n; 25 int getfather(int x){ 26 if (fa[x]!=x) fa[x]=getfather(fa[x]); 27 return fa[x]; 28 } 29 int main(){ 30 read(n); 31 int x; 32 F(i,1,n) fa[i]=i; 33 F(i,1,n){ 34 read(x); 35 int f1=getfather(i),f2=getfather(x); 36 if (f1!=f2) fa[f1]=f2; 37 } 38 int ans=0; 39 F(i,1,n) if (fa[i]==i) ans++; 40 printf("%d\n",ans); 41 return 0; 42 }
时间: 2024-10-27 08:10:14