解题笔记——NIT 遥远的村庄
某个小镇有 N 个村庄,村庄编号1-N,给出 M 条单向道路,不存在环,即不存在 村庄A可以到达村庄B 且 村庄B也可以到达村庄A的情况。
如果村庄A与村庄B之间存在一条单向道路,则说村庄A和村庄B之间存在联系,联系具有无向性,即如果村庄A和村庄B有联系,则村庄B和村庄A有联系;联系具有传递性,即如果存在村庄A和村庄B有联系,村庄B和村庄C有联系,则村庄A和村庄C有联系。
现在小镇要在某些村庄里建垃圾站,对建垃圾站的村庄要满足与之有联系的村庄都可以通过单向道路到达该村庄。问小镇能建多少个垃圾站。
Input
输入包含多组数据,对于每组数据:
第一行输入N,M,数据范围1<=n<=1000,0<=m<10000。
接下来M行,每行两个整数,s,t,代表 s 可以到达 t 。
Output
对于每组数据,输出一个整数代表答案。
Sample Input
10 6
1 2
2 3
3 4
6 7
7 8
9 10
Sample Output
4
Hint
案例中有10个村庄,道路情况如下:
1->2->3->4
5
6->7->8
9->10
村庄4可以建垃圾站,因为与之有联系的村庄都能到达他;同理村庄5,村庄8,村庄10,所以答案有4个。
解题思路:
要建垃圾站的话,该村庄所在的关于村庄联系的联通块内的结点数和他的单向道路能到达的结点数相同,但是建边要反向建,本来u到v的边要建成v到u的边,用并查集算各个联通块内结点数,然后dfs算能到达多少个结点再跟该联通块内结点总数比较,相等的话说明可以建垃圾站
难点在看不懂题意
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
#define INF 0x3f3f3f3f
const ll MAXN = 1e3 + ;
const ll MAXM = 1e4 + ;
const ll MOD = 1e9 + ;
const double pi = acos(-);
int n, m;
int vis[MAXN];
int pre[MAXN];
vector<int> V[MAXN];
int root[MAXN]; //根结点的位置记录联通块内结点数
int cnt;
void init()
{
memset(vis, , sizeof(vis));
memset(root, , sizeof(root));
for (int i = ; i <= n; i++)
pre[i] = i, V[i].clear();
}
int find(int x) //查找根结点
{
int r = x;
while (r != pre[r]) //寻找根结点
r = pre[r];
int i = x, j;
while (pre[i] != r) //路径压缩
{
j = pre[i];
pre[i] = r;
i = j;
}
return r;
} //并查集求联通块块数
//遍历有向图结点
void DFS(int u)
{
cnt++;
vis[u] = ;
for (int i = ; i < V[u].size(); i++)
{
int v = V[u][i];
if (!vis[v])
{ //如果该节点未被访问,则深度遍历
DFS(v);
}
}
}
int main()
{
while (~scanf("%d%d", &n, &m))
{
init();
int ans = ;
for (int i = ; i < m; i++)
{
int u, v;
scanf("%d%d", &u, &v);
V[v].push_back(u);
int fa = find(u);
int fb = find(v);
if (fa != fb)
pre[fa] = fb;
}
for (int i = ; i <= n; i++)
root[find(i)]++;
for (int i = ; i <= n; i++)
{
memset(vis, , sizeof(vis));
cnt = ;
DFS(i);
if (cnt == root[find(i)])
ans++;
}
printf("%d\n", ans);
}
return ;
}
/* 14 7
1 8
2 8
4 5
7 8
9 7
6 7
6 8
*/
解题笔记——NIT 遥远的村庄的更多相关文章
- 《剑指offer》解题笔记
<剑指offer>解题笔记 <剑指offer>共50题,这两周使用C++花时间做了一遍,谨在此把一些非常巧妙的方法.写代码遇到的难点.易犯错的细节等做一个简单的标注,但不会太过 ...
- 122. Best Time to Buy and Sell Stock(二) leetcode解题笔记
122. Best Time to Buy and Sell Stock II Say you have an array for which the ith element is the price ...
- 110.Balanced Binary Tree Leetcode解题笔记
110.Balanced Binary Tree Given a binary tree, determine if it is height-balanced. For this problem, ...
- 2016/9/21 leetcode 解题笔记 395.Longest Substring with At Least K Repeating Characters
Find the length of the longest substring T of a given string (consists of lowercase letters only) su ...
- LeetCode解题笔记 - 3. Longest Substring Without Repeating Characters
Given a string, find the length of the longest substring without repeating characters. Examples: Giv ...
- LeetCode解题笔记 - 2. Add Two Numbers
2. Add Two Numbers You are given two non-empty linked lists representing two non-negative integers. ...
- HDU-5902-GCD is Funny解题笔记
Alex has invented a new game for fun. There are n integers at a board and he performs the following ...
- CTF实验吧-WEB题目解题笔记(1)简单的登陆题
1.简单的登陆题 解题链接: http://ctf5.shiyanbar.com/web/jiandan/index.php Burp抓包解密 乱码,更换思路.尝试id intruder 似乎也没什 ...
- PTA 乙级解题笔记 1001 害死人不偿命的(3n+1)猜想
卡拉兹(Callatz)猜想: 对任何一个正整数 n,如果它是偶数,那么把它砍掉一半:如果它是奇数,那么把 (3n+1) 砍掉一半.这样一直反复砍下去,最后一定在某一步得到 n=1.卡拉兹在 1950 ...
随机推荐
- AI炼丹 - 深度学习必备库 numpy
目录 深度学习必备库 - Numpy 1. 基础数据结构ndarray数组 1.1 为什么引入ndarray数组 1.2 如何创建ndarray数组 1.3 ndarray 数组的基本运算 1.4 n ...
- docker.service 修改指南
vi /lib/systemd/system/docker.service docker.service默认内容如下: [Unit] Description=Docker Application Co ...
- 工具系列 | Docker基本概念小结
▍什么是Docker? Docker 是一个开源的应用容器引擎,让开发者可以打包他们的应用以及依赖包到一个可移植的镜像中,然后发布到任何流行的 Linux或Windows 机器上,也可以实现虚拟化.容 ...
- $Luogu2512/CH122/AcWing122$糖果传递 模拟
$Luogu$ $AcWing$ $Description$ 有$n$个小朋友坐成一圈,每人有$a_i$个糖果. 每人只能给左右两人传递糖果. 每人每次传递一个糖果代价为$1$. 求使所有人获得均等 ...
- 前端Tips#3 - 简写的 border-radius 100% 和 50% 是等效的
本文同步自 JSCON简时空 - 技术博客,点击阅读 视频讲解 视频地址 文字讲解 1.先讲结论 border-radius 这个 css 属性大家应该使用得非常娴熟,现实中用到的场景基本都是四个圆角 ...
- centos7+docker+elasticsearch 安装记录+踩坑
版本: cenos7 :3.10.0-957.21.3.el7.x86_64 (内核需>=3.10 才可以安装) docker: yum安装版本为1.13.1 elasticsearch: 6 ...
- spring boot事务管理
spring boot集成事务十分的简单,只需要在启动类上面增加@EnableTransactionManagement注解,然后在需要实现事务的方法上添加@Transactional注解就可以了.下 ...
- ORA-00903表名无效关于${}和#{}的使用
相当于对数据 加上 双引号,$相当于直接显示数据 ${xxx}这样格式的参数会直接参与SQL编译,从而不能避免注入攻击 但可以使用在from之后传入表名 {}占位符? where之后 防止注入
- 2019年全网最热门的123个Java并发面试题总结
前言 并发编程几乎是所有互联网公司面试必问的问题,并发编程是Java程序员最重要的技能之一,也是最难掌握的一种技能.它要求编程者对计算机最底层的运作原理有深刻的理解,同时要求编程者逻辑清晰.思维缜密, ...
- mock造数据
前端开发,需要和后台联调:很多时候,前端开发并不需要等后台完全写好接口在去联调,自己可以写死数据,渲染数据,加样式.后台人员有时会很忙,他没有时间写好返回所有的数据等等,特别是新开一个项目,从零开始的 ...