• 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 }
  • 相关阅读:
    Qt中实现启动画面(延时过程中要加上app.processEvents())
    Qt5中生成和使用静态库
    360云后台(使用HTTP Cache服务器)
    lucene 从2.4.0—3.6.0—4.3.1版本升级
    从C++到Qt(命令行编译,讲解原理)
    赵伟国的逻辑
    windows 7 系统进程服务详解
    QT 4.87 changes
    海量小文件存储
    最大连续子序列乘积
  • 原文地址:https://www.cnblogs.com/7391-KID/p/7625962.html
Copyright © 2020-2023  润新知