zoukankan      html  css  js  c++  java
  • [BZOJ4651][NOI2016]网格(Tarjan)

    下面直接给出结论,相关证明见官方题解。

    1.若跳蚤数不超过1或仅有两只跳蚤且相邻,则答案为-1。

    2.若跳蚤形成的连通块个数大于1,则答案为0。

    3.若跳蚤之间建图存在割点,则答案为1。

    4.否则为2。

    这样就有70分了。但是图太大了,显然有很多没用的跳蚤被统计进答案。

    考虑到造成不连通的情况一定在蛐蛐附近,于是将每个蛐蛐周围5*5的格子中的24个跳蚤全部取出,内圈8个称为一级空地,外圈称为二级空地。之考虑这些点即可,复杂度就只与蛐蛐个数相关了。

    将所有被取出的跳蚤建图,求连通块个数和割点即可。

    几个注意点:

    1.特判n=1或m=1的情况。

    2.只有一级空地与在网格边缘的二级空地成为割点答案才能是0。

    3.关于常数问题:不要用memset,判断元素是否存在用S.find(x)!=S.end()不要用S.count(x)。

    4.下面代码在UOJ被叉掉了,以及O2会产生各种无解的错误,比如bool tag[N]如果写在int那行的上面就会被系统杀死。

     1 #include<map>
     2 #include<cstdio>
     3 #include<cstring>
     4 #include<algorithm>
     5 #define mem(a) memset(a,0,sizeof(a))
     6 #define rep(i,l,r) for (int i=(l); i<=(r); i++)
     7 #define For(i,x) for (int i=h[x],k; i; i=nxt[i])
     8 using namespace std;
     9 
    10 const int N=3200010;
    11 const int dx[5]={0,0,1,0,-1},dy[5]={0,1,0,-1,0};
    12 int T,n,m,c,cnt,tim,nd,id[5][5],dfn[N],low[N],fa[N],h[N],nxt[N<<2],to[N<<2];
    13 bool tag[N];
    14 struct P{ int x,y; }p[N],s[3];
    15 map<P,int>S;
    16 bool operator <(const P &a,const P &b){ return (a.x==b.x) ? a.y<b.y : a.x<b.x; }
    17 void add(int u,int v){ to[++cnt]=v; nxt[cnt]=h[u]; h[u]=cnt; }
    18 int get(int x){ return (fa[x]==x) ? x : fa[x]=get(fa[x]); }
    19 bool chk(int x,int y){ return x>=1 && x<=n && y>=1 && y<=m; }
    20 
    21 inline int rd(){
    22     int x=0; char ch=getchar();
    23     while (ch<'0' || ch>'9') ch=getchar();
    24     while (ch>='0' && ch<='9') x=(x<<3)+(x<<1)+(ch^48),ch=getchar();
    25     return x;
    26 }
    27 
    28 bool tarjan(int x,int fa){
    29     dfn[x]=low[x]=++tim; int son=0;
    30     For(i,x) if ((k=to[i])!=fa){
    31         if (dfn[k]) low[x]=min(low[x],dfn[k]);
    32         else{
    33             if (tarjan(k,x)) return 1;
    34             son++; low[x]=min(low[x],low[k]);
    35             if (((fa && low[k]>=dfn[x]) || (!fa && son>1)) && tag[x]) return 1;
    36         }
    37     }
    38     return 0;
    39 }
    40 
    41 int main(){
    42     freopen("grid.in","r",stdin);
    43     freopen("grid.out","w",stdout);
    44     for (scanf("%d",&T); T--; ){
    45         scanf("%d%d%d",&n,&m,&c); cnt=0; nd=0; tim=0; S.clear();
    46         rep(i,1,c) p[i].x=rd(),p[i].y=rd(),S[p[i]]=-1;
    47         if (1ll*n*m-c<=1){ puts("-1"); continue; }
    48         if (1ll*n*m-c==2){
    49             int tot=0;
    50             rep(i,1,n) rep(j,1,m) if (S.find((P){i,j})==S.end()) s[++tot]=(P){i,j};
    51             if (abs(s[1].x-s[2].x)+abs(s[1].y-s[2].y)==1) puts("-1"); else puts("0");
    52             continue; 
    53         }
    54         rep(i,1,c){
    55             rep(x,-2,2) rep(y,-2,2) if (chk(p[i].x+x,p[i].y+y)){
    56                 int x1=p[i].x+x,y1=p[i].y+y;
    57                 if (S.find((P){x1,y1})==S.end())
    58                     id[x+2][y+2]=++nd,S[(P){x1,y1}]=nd,tag[nd]=0,h[nd]=0,dfn[nd]=0,fa[nd]=nd;
    59                 else id[x+2][y+2]=S[(P){x1,y1}];
    60                 if (x1==1 || x1==n || y1==1 || y1==m || (abs(x)<=1 && abs(y)<=1)) tag[id[x+2][y+2]]=1;
    61             }else S[(P){p[i].x+x,p[i].y+y}]=-1,id[x+2][y+2]=-1;
    62             rep(x,0,4) rep(y,0,4) rep(k,1,4){
    63                 int x1=x+dx[k],y1=y+dy[k];
    64                 if (x1<0 || x1>4 || y1<0 || y1>4 || id[x][y]==-1 || id[x1][y1]==-1) continue;
    65                 add(id[x][y],id[x1][y1]);
    66                 fa[get(id[x1][y1])]=get(id[x][y]);
    67             }
    68         }
    69         bool flag=0;
    70         rep(i,1,c){
    71             int t=-1;
    72             rep(x,-2,2) rep(y,-2,2){
    73                 int w=S[(P){p[i].x+x,p[i].y+y}];
    74                 if (w==-1) continue;
    75                 if (t==-1) t=get(w); else { if (t!=get(w)){ flag=1; break; } }
    76             }
    77             if (flag) break;
    78         }
    79         if (flag){ puts("0"); continue; }
    80         if (n==1 || m==1){ puts("1"); continue; }
    81         rep(i,1,nd) if (!dfn[i] && tarjan(i,0)) { puts("1"); flag=1; break; }
    82         if (!flag) puts("2");
    83     }
    84     return 0;
    85 }
  • 相关阅读:
    WinRAR5.01注册码附注册机
    PS不能存储,因为程序错误
    mysql中 date datetime time timestamp 的区别
    sublime text 3 3126 注册码+中文包
    IIS7.5 用 IIS AppPool应用程序池名 做账号 将各站点权限分开
    linux vi 报错 E37: No write since last change (add ! to override)
    Linux 安装 apache2.4.23
    三级分类及名称及列表
    二级栏目名称及列表
    每隔N行输出不同样式
  • 原文地址:https://www.cnblogs.com/HocRiser/p/9916300.html
Copyright © 2011-2022 走看看