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. App.xaml介绍

    在App.xaml.cs中指定 public App () { InitializeComponent(); MainPage = new XamarinDemo.MainPage(); } 同时,这 ...

  2. MVC 自动装配

    //HelloController.cs using FirstMVC.Models; using System;using System.Collections.Generic;using Syst ...

  3. WPF 绑定到静态属性(4.5)

    1. 声明静态事件 /// <summary> /// 静态属性通知 /// </summary> public static event EventHandler<Pr ...

  4. tensorflow 1.0 学习:模型的保存与恢复

    将训练好的模型参数保存起来,以便以后进行验证或测试,这是我们经常要做的事情.tf里面提供模型保存的是tf.train.Saver()模块. 模型保存,先要创建一个Saver对象:如 saver=tf. ...

  5. C# WinForm TreeView选择父节点子节点全选

    //设置标志,防止死循环 bool check = false; public void TV_AfterCheck(object sender, TreeViewEventArgs e) { if ...

  6. SQL Server 命名实例更改端口进行发布订阅

    原文:SQL Server 命名实例更改端口进行发布订阅 两台数据库服务器,都没有加入域,都安装多实例,端口也不一样了.现在使用命名实例进行复制,折腾了好久,才发现解决方法. 服务器A:myserve ...

  7. 一键彻底关闭Win10自带Windows Defender杀毒软件

    1.以管理员身份打开系统的命令提示符[cmd.exe]. 2.输入以下命令: reg add "HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\ ...

  8. /etc/passwd和/etc/group文件详解

    用户管理 想要知道, 系统中有哪些用户, 可以查看这个文件: /etc/passwd root:x:::root:/root:/bin/bash bin:x:::bin:/bin:/sbin/nolo ...

  9. 领域驱动设计(DDD)的实践经验分享之ORM的思考

    原文:领域驱动设计(DDD)的实践经验分享之ORM的思考 最近一直对DDD(Domain Driven Design)很感兴趣,于是去网上找了一些文章来看看,发现它确实是个好东西.于是我去买了两本关于 ...

  10. .net EF Join 关联表分页查询

    Join中第二个参数和第三个参数即为两张表关联对应的字段 第四个参数new 后面如果不写Model名,系统会自动生成带字段的list类型 IQueryable<Operator> oper ...