来自FallDream的博客,未经允许,请勿转载,谢谢。
跳蚤国王和蛐蛐国王在玩一个游戏。
他们在一个 n 行 m 列的网格上排兵布阵。其中的 c 个格子中 (0≤c≤nm),每个格子有一只蛐蛐,其余的格子中,每个格子有一只跳蚤。
我们称占据的格子有公共边的两只跳蚤是相邻的。
我们称两只跳蚤是连通的,当且仅当这两只跳蚤相邻,或存在另一只跳蚤与这两只跳蚤都连通。
现在,蛐蛐国王希望,将某些(0 个,1 个或多个)跳蚤替换成蛐蛐,使得在此之后存在至少两只跳蚤不连通。
例如:我们用图表示一只跳蚤,用图表示一只蛐蛐,那么图 1 描述了一个 n=4,m=4,c=2的情况。
这种情况下蛐蛐国王可以通过将第 2 行第 2 列,和第 3 行第 3 列的两只跳蚤替换为蛐蛐,从而达成他的希望,如图 2 所示。并且,不存在更优的方案,但是可能存在其他替换 2 只跳蚤的方案。
你需要首先判断蛐蛐国王的希望能否被达成。如果能够达成,你还需要最小化被替换的跳蚤的个数。
T<=20 1≤n,m≤10^9,0≤c≤min(nm,10^5) ∑c<=10^5
2s/1G
真是很蛋疼
当跳蚤数量小于2或者正好是一对还粘一起的时候答案是-1
当跳蚤本身不联通的时候答案是0
当存在一个点把图割开的时候是1
不然就是2
好像很简单 乱写了一通之后 成功获得了16分 真轻松 然后就去看了看题解
只保留在蛐蛐周围的5*5的格子内的跳蚤,四联通建图 建出的图等价 割点可以tarjan求出
然后如果有跳蚤不联通 那么会有一个蛐蛐的八联通块周围有两个不同的跳蚤联通块
感觉自己的码力不是很行啊 乱写一通 就这么丑了(吐血)
#include<iostream> #include<cstdio> #include<vector> #include<cstring> #define ll long long #define MN 100000 #define mod 2333333 using namespace std; inline int read() { int x = 0; char ch = getchar(); while(ch < '0' || ch > '9') ch = getchar(); while(ch >= '0' && ch <= '9'){x = x * 10 + ch - '0';ch = getchar();} return x; } int n,m,c,top,dn,ans,bel[MN*25+5],Cnt=0,Col=0,head[MN*25+5],en,tot,dfn[MN*25+5],low[MN*25+5],col[MN*2+5]; vector<int> v[MN+5],V[MN+5]; bool Cut[MN*25+5],b[MN+5]; struct P { int x,y; P(int x=0,int y=0):x(x),y(y){} P operator+(P b){return P(x+b.x,y+b.y);} }p[MN+5],Q[5],q[MN*25+5]; struct edge{int to,next;}e[MN*100+5]; struct My_Map { int Head[mod+5],cnt; struct Hash{ll ha;int x,next;}s[25*MN+5]; void clear() { cnt=0; memset(Head,0,sizeof(Head)); } void ins(int X,int Y) { ll Ha=1LL*X*m+Y;int j=Ha%mod; s[++cnt]=(Hash){Ha,++Cnt,Head[j]}; Head[j]=cnt; } int Check(int X,int Y) { ll Ha=1LL*X*m+Y;int j=Ha%mod; for(int i=Head[j];i;i=s[i].next) if(s[i].ha==Ha) return s[i].x; return 0; } }mp; inline void ins(int f,int t){e[++en]=(edge){t,head[f]};head[f]=en;} inline int abs(int x){return x<0?-x:x;} bool Check() { if(1LL*n*m-c>2) return false; if(1LL*n*m-c<=1) return true; top=0; for(int i=1;i<=n;++i) for(int j=1;j<=m&&top<2;++j) if(!mp.Check(i,j)) Q[++top]=P(i,j); if(Q[1].x==Q[2].x&&abs(Q[1].y-Q[2].y)==1) return true; if(Q[1].y==Q[2].y&&abs(Q[1].x-Q[2].x)==1) return true; return false; } const int dis[4][2]={{1,0},{-1,0},{0,1},{0,-1}}; void build() { for(int i=1;i<=c;++i) for(int j=-2;j<=2;++j) for(int k=-2;k<=2;++k) if(j||k) { int x=p[i].x+j,y=p[i].y+k; if(x<=0||y<=0||x>n||y>m||mp.Check(x,y)) continue; mp.ins(x,y);q[Cnt]=P(x,y); } for(int i=1,k;i<=Cnt;++i) for(int j=0;j<4;++j) { int x=q[i].x+dis[j][0],y=q[i].y+dis[j][1]; if(x<=0||y<=0||x>n||y>m||(k=mp.Check(x,y))<=0) continue; ins(i,k); } } void tj(int x,int fa) { dfn[x]=low[x]=++dn;bel[x]=tot;Cut[x]=0;int son=0; for(int i=head[x];i;i=e[i].next)if(e[i].to!=fa) { if(!dfn[e[i].to]) { ++son,tj(e[i].to,x),low[x]=min(low[x],low[e[i].to]); if(low[e[i].to]>=dfn[x]) Cut[x]=1; } else low[x]=min(low[x],dfn[e[i].to]); } if(son==1&&!fa) Cut[x]=0; } bool Round(int id) { for(int i=-1;i<=1;++i) for(int j=-1;j<=1;++j) if(i||j) { int x=q[id].x+i,y=q[id].y+j; if(x&&y&&mp.Check(x,y)<0)return 1; } return 0; } bool check(int t) { int col=-1; for(int l=0;l<V[t].size();++l) { int X=p[V[t][l]].x,Y=p[V[t][l]].y; for(int i=-2;i<=2;++i) for(int j=-2,k;j<=2;++j) if(i||j) { int x=X+i,y=Y+j; if(x<1||y<1||x>n||y>m||(k=mp.Check(x,y))<0) continue; if(col==-1) col=bel[k]; else if(col!=bel[k]) return true; } } return false; } void Dfs(int x) { col[x]=Col;V[Col].push_back(x); for(int j=0;j<v[x].size();++j) if(!col[v[x][j]]) Dfs(v[x][j]); } int main() { for(int T=read();T;--T) { n=read();m=read();c=read();ans=2;mp.clear(); if(m==1||n==1) ans=1;Cnt=-c-1; for(int i=1;i<=c;++i) p[i].x=read(),p[i].y=read(),mp.ins(p[i].x,p[i].y); if(Check()) puts("-1"); else { Cnt=0;en=0;tot=0;dn=0;Col=0;build(); for(int i=1,k;i<=c;++i) for(int j=0;j<4;++j) { int x=p[i].x+dis[j][0],y=p[i].y+dis[j][1]; if(x<1||y<1||x>n||y>m) continue; if((k=mp.Check(x,y))<0) v[i].push_back(k+c+1); } for(int i=1;i<=c;++i) if(!col[i]) ++Col,Dfs(i); for(int i=1;i<=Cnt;++i) if(!dfn[i]) ++tot,tj(i,0); for(int i=1;i<=Cnt&&ans>1;++i) if(Cut[i]&&Round(i)) ans=1; for(int i=1;i<=Col&&ans;++i) if(check(i)) ans=0; printf("%d ",ans); memset(head,0,sizeof(int)*(Cnt+5)); for(int i=1;i<=c;++i) v[i].clear(),V[i].clear(); memset(dfn,0,sizeof(int)*(Cnt+5)); memset(low,0,sizeof(int)*(Cnt+5)); memset(col,0,sizeof(int)*(c+5)); } } return 0; }