http://codeforces.com/gym/101257/problem/F

题意:给出一个n*m的地图,上面相同数字的代表一个国家,问对于每个国家有多少个国家在它内部(即被包围)。例如第一个样例,1包围2,2包围3,所以1包围2和3,2包围3。

思路:昨晚tmk大佬给我们讲了一下这题。对于一个国家,将和它相邻的国家连边,最后形成一个图。

可以发现,如果从随便一个点出发DFS,如果失去了某个点之后,导致整个图不连通了,那么这个点就一定包围了一些国家。

例如下面这个样例:

1 1 1 1 1 1

1 2 2 2 2 1

1 2 4 3 2 1

1 2 3 3 2 1

1 2 2 2 2 1

1 1 1 1 1 1

可以画出这张图,可以发现,如果失去了2这个点,将会导致1和3、4不连通,那么2必定是包围了一些点,但是不能确认到底是包围了3、4还是包围了1。

于是可以在最外层包围一层“新世界”,这样从新世界开始DFS,如果失去了像2这样的点导致图不连通了,那么2一定是包围了不在新世界一端的点。

0 0 0 0 0 0 0 0

0 1 1 1 1 1 1 0

0 1 2 2 2 2 1 0

0 1 2 4 3 2 1 0

0 1 2 3 3 2 1 0

0 1 2 2 2 2 1 0

0 1 1 1 1 1 1 0

0 0 0 0 0 0 0 0

图变成这样了。

于是就可以使用tarjan来找割点,割点就包围了一些国家。一开始dfs一遍,维护一个sz代表子树的大小。然后如果该点是割点,就可以加上其子树的大小。

关于存边:tmk大佬们一开始的做法用了set判断重边,但是爆内存了。后来索性不管重边了,因为重边是不会影响找割点了(又不是找桥)。

如果自己来想肯定想不到QAQ。

 1 #include <bits/stdc++.h>
 2 using namespace std;
 3 #define N 1000010
 4 struct Edge {
 5     int v, nxt;
 6 } edge[N*8];
 7 int head[N], tot, sz[N], dfn[N], low[N], vis[N], ans[N], tid, mp[1010][1010], cnt;
 8
 9 void Add(int u, int v) {
10     edge[tot] = (Edge) {v, head[u]}; head[u] = tot++;
11     edge[tot] = (Edge) {u, head[v]}; head[v] = tot++;
12 }
13
14 void dfs(int u) {
15     sz[u] = 1; if(cnt < u) cnt = u;
16     vis[u] = 1;
17     for(int i = head[u]; ~i; i = edge[i].nxt) {
18         int v = edge[i].v;
19         if(vis[v]) continue;
20         dfs(v);
21         sz[u] += sz[v];
22     }
23 }
24
25 void tarjan(int u, int fa) {
26     dfn[u] = low[u] = ++tid;
27     vis[u] = 1;
28     for(int i = head[u]; ~i; i = edge[i].nxt) {
29         int v = edge[i].v;
30         if(fa == v) continue;
31         if(!dfn[v]) {
32             tarjan(v, u);
33             low[u] = min(low[u], low[v]);
34             if(low[v] >= dfn[u]) ans[u] += sz[v];
35         } else if(vis[v]) {
36             low[u] = min(low[u], dfn[v]);
37         }
38     }
39 }
40
41 int main() {
42     int n, m;
43     scanf("%d%d", &n, &m);
44     for(int i = 1; i <= n; i++) for(int j = 1; j <= m; j++) scanf("%d", &mp[i][j]);
45     memset(head, -1, sizeof(head));
46     for(int i = 0; i <= n; i++) {
47         for(int j = 0; j <= m; j++) {
48             if(mp[i][j] != mp[i+1][j]) Add(mp[i][j], mp[i+1][j]);
49             if(mp[i][j] != mp[i][j+1]) Add(mp[i][j], mp[i][j+1]);
50         }
51     }
52     dfs(0);
53     memset(vis, 0, sizeof(vis));
54     tarjan(0, -1);
55     for(int i = 1; i <= cnt; i++) printf("%d ", ans[i]);
56     return 0;
57 }

转载于:https://www.cnblogs.com/fightfordream/p/6479487.html

Codeforces Gym101257F:Islands II(求割点+思维)相关推荐

  1. 2019.11.2图论专题(AtCoder Splatter Painting、President and Roads、Shortest Cycle、ISlands II)

    D:AtCoder Grand Contest 012 Splatter Painting 题目描述 Squid喜欢在图中为一些顶点染色(毕竟是鱿鱼 ) 现在有一张由 N 个顶点和 M 条边组成的简单 ...

  2. hdu 4587 2013南京邀请赛B题/ / 求割点后连通分量数变形。

    题意:求一个无向图的,去掉两个不同的点后最多有几个连通分量. 思路:枚举每个点,假设去掉该点,然后对图求割点后连通分量数,更新最大的即可.算法相对简单,但是注意几个细节: 1:原图可能不连通. 2:有 ...

  3. uva 315 (poj 1144 求割点)

    题意:给你一张无向图,求割点的个数. 思路:输入稍微处理一下接着直接套模版. 1 #include <iostream> 2 #include <cstdio> 3 #incl ...

  4. POJ1144:Network(无向连通图求割点)

    题目:http://poj.org/problem?id=1144 求割点.判断一个点是否是割点有两种判断情况: 如果u为割点,当且仅当满足下面的1条 1.如果u为树根,那么u必须有多于1棵子树 2. ...

  5. POJ1144——网络(求割点)

    描述 电话线公司(TLC)正在建立一个新的电话有线网络.它们连接多个由1到N的整数编号的地方.没有两个地方有相同的数字.线路是双向的,并且总是连接在一起的两个地方,并且在每个地方线路结束在电话交换机中 ...

  6. POJ 1144 Network(无向图连通分量求割点)

    题目地址:POJ 1144 求割点.推断一个点是否是割点有两种推断情况: 假设u为割点,当且仅当满足以下的1条 1.假设u为树根,那么u必须有多于1棵子树 2.假设u不为树根.那么(u,v)为树枝边. ...

  7. POJ1523:SPF(无向连通图求割点)

    题目:http://poj.org/problem?id=1523 题目解析: 注意题目输入输入,防止PE,题目就是求割点,并问割点将这个连通图分成了几个子图,算是模版题吧. #include < ...

  8. [UVA315]Network(tarjan, 求割点)

    题目链接:https://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem ...

  9. 图论 —— 图的连通性 —— Tarjan 求割点与桥

    [概念] 1.割点 1)割点:删除某点后,整个图变为不连通的两个部分的点 2)割点集合:在一个无向图中删除该集合中的所有点,能使原图变成互不相连的连通块的点的集合 3)点连通度:最小割点集合点数 如上 ...

最新文章

  1. python文本数据增强_CVPR2020场景文字数据增强(纯python实现)
  2. linux怎么让某一个组对一文件可读可写,设置linux文件权限,使得同一用户组的可以对一个文件自由修改...
  3. CentOS文件权限管理
  4. lock交替打印_面试题Synchronized实现两个线程交替打印
  5. 网络安全-windows批处理
  6. php邮件代码c语言,C语言实现邮件发送功能(SMTP)源码
  7. html5canvas简单画图
  8. 【深入浅出etcd系列】1. 架构概览
  9. 微软公告:Visual Basic 6 完全兼容 Windows 8 的整个产品周期
  10. 六大洲客户的特点,收藏备用~
  11. 解决打印机问题的方法
  12. 数据库课设——简单的图书管理系统
  13. woff文件 服务器上找不到,vue Iview 项目部署到服务器上woff2文件 net::ERR_ABORTED 404 (Not Found)怎么处理?...
  14. 心动的本质是什么_风动,幡动,仁者心动,到底是什么在动
  15. 《分解因数》:质因数分解
  16. 【win】WINDOWS10系统自带桌面整理工具
  17. 动态图册用HTML怎么制作,imgplay gif动图制作如何使用?imgplay图文使用教程
  18. 常用计算机字长,计算机基本单位——位、字节、字、字长
  19. 关于我所上传资源的相关问题
  20. gradle全集 下载 蓝凑云(非百度网盘)

热门文章

  1. 从代理机制到Spring AOP,这篇给你安排的明明白白的
  2. 为什么大家都说 SELECT * 效率低?
  3. Spring Boot 异步请求和异步调用,一文搞定!
  4. 手把手教你实现一个 JSON 解析器!
  5. windows 修改hosts 立即生效的方法
  6. c语言排序算法实际案例,[C语言] 部分经典排序算法详解(有图解)
  7. 二阶矩阵转置怎么求_矩阵求导术(下)
  8. 计算机中的信息表示 ppt模板,计算机中信息的表示.ppt
  9. 高低压验电笔应用口诀及使用方法
  10. java判断表是否存在_java怎么判断表是否存在?