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。

 #include <bits/stdc++.h>
using namespace std;
#define N 1000010
struct Edge {
int v, nxt;
} edge[N*];
int head[N], tot, sz[N], dfn[N], low[N], vis[N], ans[N], tid, mp[][], cnt; void Add(int u, int v) {
edge[tot] = (Edge) {v, head[u]}; head[u] = tot++;
edge[tot] = (Edge) {u, head[v]}; head[v] = tot++;
} void dfs(int u) {
sz[u] = ; if(cnt < u) cnt = u;
vis[u] = ;
for(int i = head[u]; ~i; i = edge[i].nxt) {
int v = edge[i].v;
if(vis[v]) continue;
dfs(v);
sz[u] += sz[v];
}
} void tarjan(int u, int fa) {
dfn[u] = low[u] = ++tid;
vis[u] = ;
for(int i = head[u]; ~i; i = edge[i].nxt) {
int v = edge[i].v;
if(fa == v) continue;
if(!dfn[v]) {
tarjan(v, u);
low[u] = min(low[u], low[v]);
if(low[v] >= dfn[u]) ans[u] += sz[v];
} else if(vis[v]) {
low[u] = min(low[u], dfn[v]);
}
}
} int main() {
int n, m;
scanf("%d%d", &n, &m);
for(int i = ; i <= n; i++) for(int j = ; j <= m; j++) scanf("%d", &mp[i][j]);
memset(head, -, sizeof(head));
for(int i = ; i <= n; i++) {
for(int j = ; j <= m; j++) {
if(mp[i][j] != mp[i+][j]) Add(mp[i][j], mp[i+][j]);
if(mp[i][j] != mp[i][j+]) Add(mp[i][j], mp[i][j+]);
}
}
dfs();
memset(vis, , sizeof(vis));
tarjan(, -);
for(int i = ; i <= cnt; i++) printf("%d ", ans[i]);
return ;
}

Codeforces Gym101257F:Islands II(求割点+思维)的更多相关文章

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

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

  2. Tarjan应用:求割点/桥/缩点/强连通分量/双连通分量/LCA(最近公共祖先)【转】【修改】

    一.基本概念: 1.割点:若删掉某点后,原连通图分裂为多个子图,则称该点为割点. 2.割点集合:在一个无向连通图中,如果有一个顶点集合,删除这个顶点集合,以及这个集合中所有顶点相关联的边以后,原图变成 ...

  3. poj1523 求割点 tarjan

    SPF Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 7678   Accepted: 3489 Description C ...

  4. [学习笔记]tarjan求割点

    都口胡了求割边,就顺便口胡求割点好了QAQ 的定义同求有向图强连通分量. 枚举当前点的所有邻接点: 1.如果某个邻接点未被访问过,则访问,并在回溯后更新 2.如果某个邻接点已被访问过,则更新 对于当前 ...

  5. tarjan算法求割点cojs 8

    tarjan求割点:cojs 8. 备用交换机 ★★   输入文件:gd.in   输出文件:gd.out   简单对比时间限制:1 s   内存限制:128 MB [问题描述] n个城市之间有通讯网 ...

  6. UESTC 900 方老师炸弹 --Tarjan求割点及删点后连通分量数

    Tarjan算法. 1.若u为根,且度大于1,则为割点 2.若u不为根,如果low[v]>=dfn[u],则u为割点(出现重边时可能导致等号,要判重边) 3.若low[v]>dfn[u], ...

  7. loj 1063(求割点个数)

    题目链接:http://acm.hust.edu.cn/vjudge/problem/viewProblem.action?id=26780 思路:判断一个点是否是割点的两个条件:1.如果一个点v是根 ...

  8. POJ 1144 Network(Tarjan求割点)

    Network Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 12707   Accepted: 5835 Descript ...

  9. (转)Tarjan应用:求割点/桥/缩点/强连通分量/双连通分量/LCA(最近公共祖先)

    基本概念: 1.割点:若删掉某点后,原连通图分裂为多个子图,则称该点为割点. 2.割点集合:在一个无向连通图中,如果有一个顶点集合,删除这个顶点集合,以及这个集合中所有顶点相关联的边以后,原图变成多个 ...

随机推荐

  1. multi-node和generic-pool两大利器

    1.multi-node node只能单进程,单cpu工作,而multi-node则可以让node在多进程下共享内存的工作,实现机制是依靠child_process的sendmsg做到的.想要了解具体 ...

  2. WPF listview item mouse enter/over popup

    This is because the routing strategy of the Loaded event is Direct, which means that the routed even ...

  3. Visifire charts AxisLabels FontSize

    <charts:Chart.AxesX> <charts:Axis LineThickness="0.25" > <charts:Axis.AxisL ...

  4. QRCode二维码生成方案及其在带LOGO型二维码中的应用(2)

    原文:QRCode二维码生成方案及其在带LOGO型二维码中的应用(2) 续前:QRCode二维码生成方案及其在带LOGO型二维码中的应用(1)  http://blog.csdn.net/johnsu ...

  5. 【WPF】wpf用MultiBinding解决Converter需要动态传参的问题,以Button为例

    原文:[WPF]wpf用MultiBinding解决Converter需要动态传参的问题,以Button为例       用Binding并通过Converter转换的时候,可能偶尔会遇到传参的问题, ...

  6. Android 开发相关

    1.app下载更新 https://git.oschina.net/lwngreat/UpdateHelper

  7. 使用ArcGIS Server发布我们的数据

    原文:使用ArcGIS Server发布我们的数据 引言 上一篇我们已经安装好了ArcGIS体系的服务软件,这一篇将介绍如何把我们自己的数据通过ArcGIS Server发布出去,并且能够通过Web页 ...

  8. How to setup Assigned Access in Windows 10 (Kiosk Mode) 设置分配的访问权限(Kiosk模式)

    Let’s say you’re building some sort of ingenious mechanical contraption to be displayed in public th ...

  9. 为javasript中对象与json串之间转换的总结。

    jQuery.json 是 jQuery 的一个插件,可轻松实现对象和 JSON 字符串之间的转换.可序列化 JavaScript 对象.数值.字符串和数组到 JSON 字符串,同时可转换 JSON ...

  10. Python中的参数传递问题

    首先需要说明python中元组,列表,字典的区别. 列表: 什么是列表呢?我觉得列表就是我们日常生活中经常见到的清单. 例如:lst = ['arwen',123] 向list中添加项有两种方法:ap ...