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. HDU 2686 Matrix 3376 Matrix Again(费用流)

    HDU 2686 Matrix 题目链接 3376 Matrix Again 题目链接 题意:这两题是一样的,仅仅是数据范围不一样,都是一个矩阵,从左上角走到右下角在从右下角走到左上角能得到最大价值 ...

  2. Visifire charts ToolBar

    <charts:Chart x:Name="ChartPat" Theme="Theme2" BorderBrush="Gray" P ...

  3. AngularJS table循环数据

    <div ng-app="CycleTableApp" ng-controller="CycleTableContrl as vm"> <h1 ...

  4. jquery动态创建元素

    <!DOCTYPE html><html><head><meta http-equiv="Content-Type" content=&q ...

  5. 【转】关于List排序的时效性

    不多说了,就是说明List排序的时效性,仅仅用来备忘,改造自: http://blog.csdn.net/wanzhuan2010/article/details/6205884,感谢原作者 usin ...

  6. 使注解@ContextConfiguration同时支持locations和classes

    @Configuration @ImportResource("classpath:META-INF/dataContext.xml") class TestConfig { } ...

  7. System.Data.SQLite 中GUID的处理

    原文:System.Data.SQLite 中GUID的处理 项目中正好用到System.Data.SQLite,在手持上使用这个数据库,因为要做数据同步,所以表中的主键都是Guid的数据类型. 在数 ...

  8. Win10《芒果TV》商店版更新v3.2.7:修复下载任务和会员下载权限异常

    在第89届奥斯卡颁奖典礼,<爱乐之城>摘获最佳导演.女主.摄影等六项大奖,<月光男孩>爆冷获最佳影片之际,Win10版<芒果TV>迅速更新至v3.2.7,主要是修复 ...

  9. Linux下如何查看高CPU占用率线程 专题

    Java 系统性能分析 命令 1. cpu分析 top , pidstat(sysstat) pid -p PID -t 1 10 vmstat 1 CPU上下文切换.运行队列.利用率 ps Hh - ...

  10. 企业级架构 MVVM 模式指南 (WPF 和 Silverlight 实现) 译(3)

    第一章 表现模式关注分离(soc)是企业及软件开发中非常有用的核心原则,也是许多表现模式背后的驱动力量.在WPF和Silverlight开发中,MVVM成为了实现关注分离最为有效的设计模式.然而,这种 ...