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
",ans[i]);
126 //        if(ans[i]!=ANS[i])cout<<"WA"<<endl;
127     }
128         //printf("%d
",ans[i]);
129     return 0;
130 }
原文地址:https://www.cnblogs.com/7391-KID/p/7625962.html