http://www.luogu.org/problem/show?pid=1141
多询问题,求无向图的子连通块大小。
直接bfs,读一个搜一个,过60;
100%的点1,000,000个点,100,000次询问,显然是记忆化。
我很弱,最开始开了个数组记录每个点属于的连通块的第一个点的坐标,然后写了一堆,自己都烦。
后来问某大神,似拨开云雾见到了青天。用cnt记录连通块的" 名字 "。
学会了这一招,不代表过了。
我还是读一个点,如果访问过就输出,没访问就dfs,然后每dfs就循环一次,给所有连通块内的点赋值。代码如下
1 #include<iostream> 2 #include<cstdio> 3 #include<cmath> 4 #include<string> 5 #include<cstring> 6 #include<queue> 7 #include<cstdlib> 8 #include<algorithm> 9 #define for1(i,n,m) for(int i=(n);i<=(m);i++) 10 #define for2(i,n,m) for(int i=(n);i>=(m);i--) 11 using namespace std; 12 int n,cnt=1,m,a[1005][1005],ans[1005][1005],v[1005][1005],f1[4]={0,0,1,-1},f2[4]={-1,1,0,0}; 13 struct node 14 { 15 int x,y; 16 }; 17 queue <node> q; 18 19 void bfs(int x,int y) 20 { 21 22 q.push({x,y}); 23 v[x][y]=cnt; 24 int ans1=0; 25 while(!q.empty()) 26 { 27 node e=q.front(); 28 q.pop(); 29 ans1++; 30 for1(i,0,3) 31 { 32 int x1=e.x+f1[i],y1=e.y+f2[i]; 33 if(!v[x1][y1]&&a[x1][y1]==3-a[e.x][e.y]&&x1>0&&y1>0&&x1<=n&&y1<=n) 34 { 35 36 v[x1][y1]=cnt; 37 q.push({x1,y1}); 38 } 39 } 40 } 41 for1(i,1,n) 42 for1(j,1,n) 43 { 44 if(v[i][j]==cnt) 45 ans[i][j]=ans1; 46 47 } 48 cnt++; 49 } 50 51 int main() 52 { 53 cin>>n>>m; 54 for1(i,1,n) 55 for1(j,1,n) 56 { 57 char ch=getchar(); 58 while(ch!=‘1‘&&ch!=‘0‘) 59 ch=getchar(); 60 if(ch==‘1‘) 61 a[i][j]=1; 62 if(ch==‘0‘) 63 a[i][j]=2; 64 } 65 for1(i,1,m) 66 { 67 int x,y; 68 cin>>x>>y; 69 if(!v[x][y]) 70 bfs(x,y); 71 cout<<ans[x][y]<<endl;; 72 } 73 }
超时代码
自己好蠢,根本没好好用上cnt
超时以后去问那个大神
他说复杂度应该是O(n^2+m)
我一脸懵逼
仔细一看他的代码,感觉自己脑子有泡。
之后开了个 t[ i ] 数组作桶,记录属于 i 的联通块的大小。
一遍dfs,求所有连通块,并且分组,分别记录大小。
最后输出。。。
代码如下
1 #include<iostream> 2 #include<cstdio> 3 #include<cmath> 4 #include<string> 5 #include<cstring> 6 #include<queue> 7 #include<cstdlib> 8 #include<algorithm> 9 #define for1(i,n,m) for(int i=(n);i<=(m);i++) 10 #define for2(i,n,m) for(int i=(n);i>=(m);i--) 11 using namespace std; 12 int n,cnt=1,m,a[1005][1005],ans[1005][1005],f1[4]={0,0,1,-1},f2[4]={-1,1,0,0}; 13 int t[1005000];//用一个桶记录每一组的ans 14 int v[1005][1005];//分组,同一个连通块内的点赋相同的值,用cnt计数,以表示连通块的"名字" 15 struct node 16 { 17 int x,y; 18 }; 19 queue <node> q; 20 21 int bfs(int x,int y) 22 { 23 24 q.push({x,y}); 25 v[x][y]=cnt; 26 int ans1=0; 27 while(!q.empty()) 28 { 29 node e=q.front(); 30 q.pop(); 31 ans1++; 32 for1(i,0,3) 33 { 34 int x1=e.x+f1[i],y1=e.y+f2[i]; 35 if(!v[x1][y1]&&a[x1][y1]==3-a[e.x][e.y]&&x1>0&&y1>0&&x1<=n&&y1<=n) 36 { 37 38 v[x1][y1]=cnt; 39 q.push({x1,y1}); 40 } 41 } 42 } 43 cnt++; 44 return ans1; 45 } 46 47 int main() 48 { 49 cin>>n>>m; 50 for1(i,1,n) 51 for1(j,1,n) 52 { 53 char ch=getchar(); 54 while(ch!=‘1‘&&ch!=‘0‘) 55 ch=getchar(); 56 if(ch==‘1‘) 57 a[i][j]=1; 58 if(ch==‘0‘) 59 a[i][j]=2; 60 } 61 for1(i,1,n) 62 for1(j,1,n) 63 { 64 if(!v[i][j]) 65 { 66 int tmp=bfs(i,j); 67 t[cnt-1]=tmp; 68 }} 69 for1(i,1,m) 70 { 71 int x,y; 72 cin>>x>>y; 73 74 cout<<t[v[x][y]]<<endl; 75 } 76 }
时间: 2024-10-05 22:13:30