ACM ICPC 2017 Warmup Contest 1 A. Artwork(逆向+dfs+并查集)
链接:https://nanti.jisuanke.com/t/17410
分析:正向分析给跪了。。逆向考虑的话,先模拟一遍,记录下每个黑点被第一次涂黑的时间,然后按时间倒着来,每次把该时间变黑的那些块变白,然后ans++,然后考虑加了这一块以后连通了某些块(包括刚刚变白的这块),把通过连通减少的减去,更新答案即可。最后一个的答案可以用dfs搞一下,注意直接递归写会爆栈。。
复杂度为O(n*m*q)。
1 #include<iostream> 2 #include<cstdio> 3 #include<cstring> 4 #include<vector> 5 #include<fstream> 6 #include<stack> 7 using namespace std; 8 const int maxn=1001,inf=1e9; 9 int p[maxn*maxn]; 10 int Find(int x){return p[x]==x?x:p[x]=Find(p[x]);} 11 int n,m,q,color[maxn][maxn]; 12 int ans[10005]; 13 bool vis[maxn][maxn]; 14 vector<int> t[10005]; 15 void Print(){ 16 for(int i=1;i<=n;i++){ 17 for(int j=1;j<=m;j++){ 18 int x=Find(i*maxn+j); 19 cout<<x/maxn<<','<<x%maxn<<' '; 20 } 21 cout<<endl; 22 } 23 } 24 struct Statu{ 25 int x,y; 26 Statu(int _x,int _y):x(_x),y(_y){} 27 }; 28 void dfs(int x,int y,int fa){ 29 stack<Statu> sta; 30 sta.push(Statu(x,y)); 31 while(!sta.empty()){ 32 x=sta.top().x;y=sta.top().y; 33 p[x*maxn+y]=fa; 34 sta.pop(); 35 if(x<n&&!color[x+1][y]&&!vis[x+1][y]){ 36 vis[x+1][y]=true;sta.push(Statu(x+1,y)); 37 } 38 if(x>1&&!color[x-1][y]&&!vis[x-1][y]){ 39 vis[x-1][y]=true;sta.push(Statu(x-1,y)); 40 } 41 if(y<m&&!color[x][y+1]&&!vis[x][y+1]){ 42 vis[x][y+1]=true;sta.push(Statu(x,y+1)); 43 } 44 if(y>1&&!color[x][y-1]&&!vis[x][y-1]){ 45 vis[x][y-1]=true;sta.push(Statu(x,y-1)); 46 } 47 } 48 } 49 int main(){ 50 scanf("%d%d%d",&n,&m,&q); 51 int x1,y1,x2,y2; 52 for(int i=1;i<=n;i++){ 53 for(int j=1;j<=m;j++) 54 p[i*maxn+j]=i*maxn+j; 55 } 56 for(int i=0;i<q;i++){ 57 scanf("%d%d%d%d",&x1,&y1,&x2,&y2); 58 if(y1==y2){ 59 for(int j=x1;j<=x2;j++){ 60 if(!color[j][y1]){ 61 t[i].push_back(j*maxn+y1); 62 color[j][y1]=1; 63 } 64 } 65 }else{ 66 for(int j=y1;j<=y2;j++){ 67 if(!color[x1][j]){ 68 t[i].push_back(x1*maxn+j); 69 color[x1][j]=1; 70 } 71 } 72 } 73 } 74 ans[q]=0; 75 for(int i=1;i<=n;i++){ 76 for(int j=1;j<=m;j++){ 77 if(color[i][j]||vis[i][j])continue; 78 dfs(i,j,i*maxn+j);ans[q]++; 79 } 80 } 81 for(int T=q-1;T>0;T--){ 82 ans[T]=ans[T+1]; 83 for(int i=0;i<t[T].size();i++){ 84 int x=t[T][i]/maxn,y=t[T][i]%maxn,count=0; 85 color[x][y]=0; 86 int Fa=t[T][i],H; 87 ans[T]++; 88 if(x>1&&!color[x-1][y]){ 89 H=Find((x-1)*maxn+y); 90 if(H!=Fa){ 91 ans[T]--; 92 p[H]=Fa; 93 } 94 count++; 95 } 96 if(x<n&&!color[x+1][y]){ 97 H=Find((x+1)*maxn+y); 98 if(H!=Fa){ 99 ans[T]--; 100 p[H]=Fa; 101 } 102 count++; 103 } 104 if(y>1&&!color[x][y-1]){ 105 H=Find(x*maxn+y-1); 106 if(H!=Fa){ 107 ans[T]--; 108 p[H]=Fa; 109 } 110 count++; 111 } 112 if(y<m&&!color[x][y+1]){ 113 H=Find(x*maxn+y+1); 114 if(H!=Fa){ 115 ans[T]--; 116 p[H]=Fa; 117 } 118 count++; 119 } 120 // cout<<x<<' '<<y<<endl; 121 // Print(); 122 } 123 } 124 for(int i=1;i<=q;i++){ 125 printf("%d\n",ans[i]); 126 // if(ans[i]!=ANS[i])cout<<"WA"<<endl; 127 } 128 //printf("%d\n",ans[i]); 129 return 0; 130 }