题目分析:

答案显然只有{-1,0,1,2}四种。

对于答案等于-1的情况,只有两种情况,一种是只剩一只跳蚤,另一种是只剩两只跳蚤且他们四连通,这个很好判。

对于答案等于0的情况,那说明联通块大于1,把图离散出来连边并查集判就可以了。

对于答案等于1的情况,我们要考虑唯一的联通块是否存在割顶,具体的,我们发现答案只可能是有蛐蛐的格子旁边的八个格子(n=1或m=1除外),那么把它们提取出来单独建点,而其它的离散,跑一边割顶就可以做了。

剩下的输出2.

代码:

  1 #include<bits/stdc++.h>
  2 using namespace std;
  3
  4 const int maxn = 2012000;
  5
  6 int n,m,c,tot;
  7 pair<int,int> pr[maxn];
  8 vector<pair<int,int> > vec[maxn];
  9 int arr[maxn],mlgb[maxn],isg[maxn];
 10 vector<int> g[maxn];
 11 int dx[8]={0,0,1,-1,1,-1,1,-1};
 12 int dy[8]={1,-1,0,0,1,-1,-1,1};
 13 int chk,pre[maxn];
 14 int low[maxn],dfn[maxn],cl,fa[maxn];
 15
 16 void init(){
 17     memset(pr,0,sizeof(pr));
 18     for(int i=0;i<=tot;i++) low[i]=dfn[i]=fa[i]=isg[i]=arr[i]=0;
 19     for(int i=0;i<=tot;i++) vec[i].clear(),g[i].clear();
 20     cl = chk = n = m = c = tot = 0;
 21 }
 22
 23 int found(int x){
 24     int rx = x; while(pre[rx] != rx) rx = pre[rx];
 25     while(pre[x] != rx){int tmp = pre[x]; pre[x] = rx; x = tmp;}
 26     return rx;
 27 }
 28
 29 int pd0(){
 30     sort(pr+1,pr+c+1);pr[0] = make_pair(0,m+10);
 31     int tnum = 0,pnum = 0;
 32     int zt = 0;
 33     for(int i=1;i<=c;i++) arr[++zt]=pr[i].first-1,arr[++zt]=pr[i].first+1,arr[++zt]=pr[i].first;
 34     sort(arr+1,arr+zt+1); zt = unique(arr+1,arr+zt+1)-arr-1;
 35     while(arr[zt] == n+1)zt--;
 36     for(int i=1;i<=zt;i++){
 37     if(arr[i] == 0) continue;
 38     if(arr[i] != arr[i-1]+1){vec[++tnum].push_back(make_pair(1,m));tot++;}
 39     tnum++;
 40     int lst = lower_bound(pr+1,pr+c+1,make_pair(arr[i]-1,0))-pr;
 41     int now = lower_bound(pr+1,pr+c+1,make_pair(arr[i],0))-pr;
 42     if(pr[now].first != arr[i]) now = 0;
 43     int imp=0;while(lst<=c&&pr[lst].first<=arr[i]+1) mlgb[++imp]=pr[lst].second,lst++;
 44     sort(mlgb+1,mlgb+imp+1); imp = unique(mlgb+1,mlgb+imp+1)-mlgb-1;
 45     int z = 1;int j = now,k = 1;
 46     while(z <= m){
 47         if(k > imp){vec[tnum].push_back(make_pair(z,m));tot++;z=m+1;break;}
 48         while(pr[j].first==arr[i]&&pr[j].second<mlgb[k])j++;
 49         if(z < mlgb[k]-1){vec[tnum].push_back(make_pair(z,mlgb[k]-2));tot++;z = mlgb[k]-1;}
 50         if(z < mlgb[k]){isg[++tot]=1;vec[tnum].push_back(make_pair(z,mlgb[k]-1));z = mlgb[k];}
 51         if(z==mlgb[k]&&(!(pr[j].first==arr[i]&&pr[j].second==mlgb[k]))){
 52         isg[++tot]=1;vec[tnum].push_back(make_pair(z,mlgb[k]));z = mlgb[k]+1;
 53         }else z = mlgb[k]+1;
 54         if(z > m) break;
 55         while(pr[j].first==arr[i]&&pr[j].second<mlgb[k]+1)j++;
 56         if(!(pr[j].first==arr[i]&&pr[j].second==mlgb[k]+1)){
 57         isg[++tot]=1;vec[tnum].push_back(make_pair(z,mlgb[k]+1));z = mlgb[k]+2;
 58         }
 59         k++;
 60     }
 61     }
 62     if(arr[zt] != n){vec[++tnum].push_back(make_pair(1,m));tot++;}
 63     for(int i=0;i<tot;i++) pre[i] = i;
 64     for(int i=1;i<tnum;i++){
 65     int k = 0;
 66     for(int j=0;j<vec[i].size();j++){
 67         while(k<vec[i+1].size()&&vec[i+1][k].second < vec[i][j].first) k++;
 68         while(k<vec[i+1].size()&&vec[i+1][k].second <= vec[i][j].second){
 69         g[pnum+j].push_back(pnum+vec[i].size()+k);
 70         g[pnum+vec[i].size()+k].push_back(pnum+j);
 71         pre[found(pnum+j)] = found(pnum+vec[i].size()+k); k++;
 72         }
 73         if(k<vec[i+1].size()&&vec[i+1][k].first <= vec[i][j].second){
 74         g[pnum+j].push_back(pnum+vec[i].size()+k);
 75         g[pnum+vec[i].size()+k].push_back(pnum+j);
 76         pre[found(pnum+j)] = found(pnum+vec[i].size()+k);
 77         }
 78     }
 79     pnum += vec[i].size();
 80     }
 81     pnum = 0;
 82     for(int i=1;i<=tnum;i++){
 83     for(int j=1;j<vec[i].size();j++){
 84         if(vec[i][j].first == vec[i][j-1].second+1){
 85         g[pnum+j].push_back(pnum+j-1);
 86         g[pnum+j-1].push_back(pnum+j);
 87         pre[found(pnum+j)] = found(pnum+j-1);
 88         }
 89     }
 90     pnum += vec[i].size();
 91     }
 92     int hh = 0;
 93     for(int i=0;i<tot;i++){if(pre[i] == i) hh++;}
 94     if(hh>1) return 1; else return 0;
 95 }
 96
 97 void Tarjan(int now){
 98     low[now] = dfn[now] = ++cl;
 99     for(int i=0;i<g[now].size();i++){
100     if(g[now][i] == fa[now]) continue;
101     if(dfn[g[now][i]] > dfn[now]) continue;
102     if(dfn[g[now][i]] == 0){
103         fa[g[now][i]] = now;Tarjan(g[now][i]);
104         low[now] = min(low[now],low[g[now][i]]);
105     }else{low[now] = min(low[now],dfn[g[now][i]]);}
106     }
107     if(isg[now+1]==0)return;
108     if(now != 0){
109     for(int i=0;i<g[now].size();i++){
110         if(fa[g[now][i]] != now) continue;
111         if(low[g[now][i]] >= dfn[now]){chk=1;}
112     }
113     }else{
114     int nh = 0;
115     for(int i=0;i<g[now].size();i++){if(fa[g[now][i]] == now){nh++;}}
116     if(nh > 1) chk++;
117     }
118 }
119
120 void read(){
121     scanf("%d%d%d",&n,&m,&c);
122     for(int i=1;i<=c;i++){scanf("%d%d",&pr[i].first,&pr[i].second);}
123 }
124
125 void work(){
126     if(1ll*n*m-c <= 1){puts("-1");return;}
127     if(1ll*n*m-c == 2){
128     sort(pr+1,pr+c+1); pair<int,int> l1,l2;
129     for(int i=1;i<=n;i++) for(int j=1;j<=m;j++){
130         int z = lower_bound(pr+1,pr+c+1,make_pair(i,j))-pr;
131         if(pr[z] == make_pair(i,j)) continue;
132         if(l1 != make_pair(0,0)) l2=make_pair(i,j); else l1=make_pair(i,j);
133     }
134     if(abs(l1.first-l2.first)+abs(l1.second-l2.second)==1){puts("-1");}
135     else puts("0");
136     return;
137     }
138     if(pd0()) {puts("0");return;}
139     if(n == 1 || m == 1){puts("1");return;}
140     Tarjan(0);
141     if(chk){puts("1");return;}
142     else puts("2");
143 }
144
145 int main(){
146     int Tmp; scanf("%d",&Tmp);
147     while(Tmp--){
148     init();
149     read();
150     work();
151     }
152     return 0;
153 }

转载于:https://www.cnblogs.com/Menhera/p/10799316.html

UOJ220 [NOI2016] 网格 【割顶】【并查集】相关推荐

  1. 并查集(Union-Find)

    并查集(Union-Find) 并查集(Union-Find) 1.初始化 2.查询 3.合并 4.平衡性优化,扁平化 5.按秩合并 6.路径压缩 7.代码 常用模板 [★ 547. 省份数量](ht ...

  2. 图 相关算法~从头学算法【广搜、 深搜、 拓扑排序、 并查集、 弗洛伊德算法、迪杰斯特拉算法】

    图的相关主流算法主要有: 广度优先搜索 深度优先搜索 拓扑排序 并查集 多源最短路径(弗洛伊德算法) 单源最短路径(迪杰斯特拉算法) 其中呢,最基本的是前两种,也就是平时常用的广搜和深搜,本文中将概要 ...

  3. NOIp 数据结构专题总结 (1):STL、堆、并查集、ST表、Hash表

    系列索引: NOIp 数据结构专题总结 (1) NOIp 数据结构专题总结 (2) STL structure std::vector #include <vector> std::vec ...

  4. 并查集 - 交换字符串中的元素

    题目链接 用并查集维护相互可以交换的索引,然后同一并查集上的字符放到小顶堆,每次取堆顶的字符重构字符串. class Solution {public:string smallestStringWit ...

  5. 并查集路径压缩_并查集(UnionFind)技巧总结

    什么是并查集 在计算机科学中,并查集是一种树型的数据结构,用于处理一些不交集(Disjoint Sets)的合并及查询问题.有一个联合-查找算法(Union-find Algorithm)定义了两个用 ...

  6. CF461D-Appleman and Complicated Task【并查集】

    正题 题目链接:https://www.luogu.com.cn/problem/CF461D 题目大意 n∗nn*nn∗n的网格需要填上xxx或ooo,其中有kkk个格子已经固定,求有多少中填写方案 ...

  7. codeforces gym-101736 Farmer Faul 平衡树+并查集

    题目 题目链接 题意 给出nnn个整数,其中1≤n≤106" role="presentation" style="position: relative;&qu ...

  8. [BZOJ4537][Hnoi2016]最小公倍数 奇怪的分块+可撤销并查集

    4537: [Hnoi2016]最小公倍数 Time Limit: 40 Sec  Memory Limit: 512 MB Submit: 1474  Solved: 521 [Submit][St ...

  9. 经典算法题:字典树、并查集、单调栈、二分、带标记函数dp、树、全排列、字符串问题等常用算法

    0. Tips 1. 位运算 如何枚举一个二进制状态数字k的子集, 方法就是针对中的二进制为1的位开始进行减法,判断数字k的二进制子集, 像枚举(2^k-1) ~ 0一样枚举其子集: int sub ...

  10. [Leedcode][JAVA][第200题][岛屿数量][DFS][BFS][并查集]

    [问题描述] 第200题 岛屿数量 给你一个由 '1'(陆地)和 '0'(水)组成的的二维网格,请你计算网格中岛屿的数量.岛屿总是被水包围,并且每座岛屿只能由水平方向和/或竖直方向上相邻的陆地连接形成 ...

最新文章

  1. python---简单的接口测试实例
  2. 历年计算机一级考试题库及答案,全国计算机一级考试试题库及答案
  3. 调整 W600 PWM的输出频率
  4. android布局如何空行,借用你的思路和框架,修复了空行、偶尔setText无效、padding设置的bug...
  5. linux 更改mysql的数据库目录
  6. “宝藏”大会NVIDIA GTC Digital来袭!这些AI前沿课程不容错过
  7. Spring Cloud Gateway介绍(一)
  8. jsplumb拖线_基于jsplumb插件制作可拖拽、保存流程图、重绘保存后的流程图总结...
  9. c语言popen函数多线程,关于多线程:多线程环境中的Python-Subprocess-Popen行为不一致...
  10. Java回调机制总结
  11. 万用表怎么测量电池容量_万用表如何测量电池容量?
  12. OSChina 娱乐弹弹弹——周一至周五,汗滴禾下土
  13. 计算机专业就业尴尬问题,计算机专业就业困境初探
  14. JavaMail实现发送邮件程序
  15. emoji表情mysql报错_MySql存储emoji表情报错的处理方法
  16. 通过Tomtit实现Perl6开发工作流程的自动化
  17. 免费无限大文件存储网盘 -- send.cm!必须收藏!操作简单,国内外都能访问,不用注册或下载,支持FTP,还带API,页面还简洁,真的爱了~
  18. VxWorks下 canOpen移植心得 stm32 - ppc
  19. 央视:乐视网是创业失败还是涉嫌欺诈?
  20. 基于NB-IoT的智慧路灯监控系统(NB-IoT专栏—实战篇5:手机应用开发)

热门文章

  1. 理财笔记 - 控制风险永远是投资的第一要素
  2. 1179: 带参宏定义(函数专题)
  3. 网页中文转英文(国际化)
  4. 家庭监控,网络摄像头(OpenWRT平台下Mjpg-Streamer+Ngrok实现方案)
  5. 谷歌十年愚人节,「玩笑」背后是美好生活的企盼
  6. 模板template基础学习
  7. Matlab无约束优化
  8. C# winform excel根据当前选中内容,自动插入/编辑批注
  9. Android 圆形调色板
  10. linux mysql免安装版配置_Linux下MySQL免安装版安装配置记录