Luo Gu P1173 / LOJ2084 / UOJ220 / BZOJ4651 [NOI2016] Grid

An obvious answer is no greater than 2 properties (fleas up to two adjacent corners)

The answer is found then only be 0, 1 (nonsense) , Category talk:

-1: $ nm-c <2 $ or $ nm-c = 2 $ and the remaining two adjacent fleas;

0: no picture communication;

1: original Unicom and has a top cut;

Otherwise 2.

But $ n, m \ le 10 ^ 9 $ scope of this data certainly can not do directly, and found that only around flea grasshoppers could be cut top, just throw them elected built drawing it?

hack :( The following are represented by grasshoppers #, * indicates flea elected Indicates the remaining fleas)

.**

.*#

.**

* To be in the middle of fake cut top. Therefore, we want to extend out twice, and then if we find the first cut at the top of the circle, then really found a cut top.

But the judge also has many connectivity pit, but many explanations did not mention, I'll mention that perhaps I was too betel a

The first is how sentence. Can not be built on the map sentenced to directly give chestnuts:

#**.**#

He will be sentenced to not communicate. The real nature of what has not communicated it? We have found that barrier point (grasshoppers) around it would point into at least two blocks Unicom, whereby Algorithm 1:

Of the selected node is four Unicom floodfill, check whether the points surrounding each obstacle link belong to the same block.

This approach has been through the official data , but we still have evil UOJ

We found this method can hack of:

*###*

Around each node is only a block Unicom, China Unicom, so you WA is heard crying out, so we have to deal with even the barriers together, get Algorithm 2:

Of the selected node is four Unicom floodfill, obstacles to eight communication floodfill, to check whether each point around the blocks in the block belong to the same link.

This is no problem.

As to achieve it, anyway map to get caught, hash and difficult to play, of course, choose hash

#include<cstdio>
#include<cstring>
#include<queue>
using namespace std;
typedef long long ll;
const int dx[4]={0,1,0,-1};
const int dy[4]={1,0,-1,0};
const int P=1000117;
const int N=100050;
char rB[1<<21],*rS,*rT;
inline char gc(){return rS==rT&&(rT=(rS=rB)+fread(rB,1,1<<21,stdin),rS==rT)?EOF:*rS++;}
inline int rd(){
    char c=gc();
    while(c<48||c>57)c=gc();
    int x=c&15;
    for(c=gc();c>=48&&c<=57;c=gc())x=(x<<3)+(x<<1)+(c&15);
    return x;
}
int x[N],y[N],G[N*24],to[N*192],nxt[N*192],sz,cnt,pre[N*24],dfsc,n,m,c,tmpx[N*24],tmpy[N*24],ctmp;
bool isok[N*24],iscut[N*24];
struct node{
    int x,y;
    node(){}
    node(int x,int y):x(x),y(y){}
};
queue<node> Q,q;
struct Hash{
    int h[P],vx[N*25],vy[N*25],p[N*25],nxt[N*25],sz;
    inline void clear(){
        memset(h,0,sizeof(h));sz=0;
    }
    inline void ins(int x,int y,int id){
        int pos=((ll)(x-1)*n+y-1)%P;
        vx[++sz]=x;vy[sz]=y;p[sz]=id;nxt[sz]=h[pos];h[pos]=sz;
    }
    inline int ask(int x,int y){
        for(int k=h[((ll)(x-1)*n+y-1)%P];k;k=nxt[k])if(vx[k]==x&&vy[k]==y)return p[k];
        return 0;
    }
}h,col,tem;
inline int Abs(int x){return x<0?-x:x;}
inline int Max(int a,int b){return a>b?a:b;}
inline void add(int u,int v){
    to[++sz]=v;nxt[sz]=G[u];G[u]=sz;
    to[++sz]=u;nxt[sz]=G[v];G[v]=sz;
}
inline bool check(){
    int i,j,k,tx,ty;
    for(i=1;i<=n;++i)
        for(j=1;j<=m;++j)if(!h.ask(i,j)){
            for(k=0;k<4;++k)if((tx=i+dx[k])&&tx<=n&&(ty=j+dy[k])&&ty<=m&&!h.ask(tx,ty))return 1;
            return 0;
        }
}
inline void bfs(int sx,int sy,int cl){  //对结点floodfill
    int i,u,v,tx,ty;
    q.push(node(sx,sy));col.ins(sx,sy,cl);
    while(!q.empty()){
        u=q.front().x;v=q.front().y;q.pop();
        for(i=0;i<4;++i)if((tx=u+dx[i])&&tx<=n&&(ty=v+dy[i])&&ty<=m&&h.ask(tx,ty)>0&&!col.ask(tx,ty)){
            col.ins(tx,ty,cl);
            q.push(node(tx,ty));
        }
    }
}
inline bool bfs2(int sx,int sy){  //对障碍floodfill
    int i,u,v,x,y,t;
    q.push(node(sx,sy));tem.ins(sx,sy,-1);
    while(!q.empty()){
        u=q.front().x;v=q.front().y;q.pop();
        for(x=Max(1,u-1);x<=n&&x<=u+1;++x)
            for(y=Max(1,v-1);y<=m&&y<=v+1;++y)if((t=h.ask(x,y))&&!tem.ask(x,y))if(t==-1){
                tem.ins(x,y,-1);
                q.push(node(x,y));
            }else{tmpx[++ctmp]=x;tmpy[ctmp]=y;}
    }
    if(ctmp==-1)return 1;
    for(i=1,t=col.ask(tmpx[0],tmpy[0]);i<=ctmp;++i)if(col.ask(tmpx[i],tmpy[i])!=t)return 0;
    return 1;
}
inline bool ncon(){
    int i,u,v,ccl=0;
    col.clear();
    while(!Q.empty()){
        u=Q.front().x;v=Q.front().y;Q.pop();
        if(col.ask(u,v))continue;
        bfs(u,v,++ccl);
    }
    tem.clear();
    for(i=0;i<c;++i)if(!tem.ask(x[i],y[i])){
        ctmp=-1;
        if(!bfs2(x[i],y[i]))return 1;
    }
    return 0;
}
int dfs(int u,int fa){
    int i,v,lowu=pre[u]=++dfsc,lowv,chd=0;
    for(i=G[u];i;i=nxt[i])if((v=to[i])!=fa)if(!pre[v]){
        ++chd;
        if((lowv=dfs(v,u))>=pre[u])iscut[u]=1;
        if(lowv<lowu)lowu=lowv;
    }else if(pre[v]<lowu)lowu=pre[v];
    if(!fa&&chd==1)iscut[u]=0;
    return lowu;
}
int main(){
    int T=rd(),i,j,k,l,t,tt,tx,ty;
    bool ok;
    while(T--){
        n=rd();m=rd();c=rd();
        h.clear();
        for(i=0;i<c;++i){
            x[i]=rd();y[i]=rd();
            h.ins(x[i],y[i],-1);
        }
        if((ll)n*m-c<2ll){
            puts("-1");
            continue;
        }
        if((ll)n*m-c==2ll){
            puts(check()?"-1":"0");
            continue;
        }
        memset(G,0,sizeof(G));ok=sz=cnt=dfsc=0;
        memset(pre,0,sizeof(pre));
        memset(iscut,0,sizeof(iscut));
        memset(isok,0,sizeof(isok));
        for(i=0;i<c;++i)
            for(j=Max(1,x[i]-2);j<=x[i]+2&&j<=n;++j)
                for(k=Max(1,y[i]-2);k<=y[i]+2&&k<=m;++k)if(!(t=h.ask(j,k))){
                    h.ins(j,k,++cnt);Q.push(node(j,k));
                    isok[cnt]=Max(Abs(j-x[i]),Abs(k-y[i]))<=1;
                    for(l=0;l<4;++l)if((tx=j+dx[l])&&tx<=n&&(ty=k+dy[l])&&ty<=m&&(tt=h.ask(tx,ty))>0)add(cnt,tt);
                }else if(t>0&&Max(Abs(j-x[i]),Abs(k-y[i]))<=1)isok[t]=1;
        "
            the puts (do not communicate with//(NCON ()) {  IF0");
            continue;
        }
        if(n==1||m==1){  //一行/一列可以特判掉
            puts("1");
            continue;
        }
        for(i=1;i<=cnt;++i){
            if(!pre[i])dfs(i,0);
            if(isok[i]&&iscut[i]){
                puts("1");
                ok=1;break;
            }
        }
        if(!ok)puts("2");
    }
    return 0;
}
View Code

 

Guess you like

Origin www.cnblogs.com/sunshine-chen/p/11302794.html