题目链接:https://www.nowcoder.com/acm/contest/76/E

题目描述

        在战争时期,A国派出了许多间谍到其他国家去收集情报。因为间谍需要隐秘自己的身份,所以他们之间只是单向联系。所以,某个间谍只能单向联系到一部分的间谍。同时,间谍也不知道跟他联系的是谁。
HA是间谍们的老大,但他也只能联系到部分的间谍。HA现在有一项命令有告诉所有的间谍。HA想要知道他至少要告诉多少个他能联系上的间谍才能通知到所有的间谍。

输入描述:

有多个测试数据。
对于每个测试数据:
第一行为一个整数n,m(0<n,m<=500)代表间谍的数量和HA能通知到的间谍的数量(间谍的编号为1-n);
第二行为m个用空格隔开的整数xi,代表HA能通知到的间谍的编号;
第三行到第n+2行,每一行第一个整数ai(0<=ai<n)表示第i-2个间谍能单向联系到的间谍数。之后有ai个用空格隔开的整数,表示间谍i-2能单向联系到的间谍的编号。

输出描述:

  输出一行,此行中有一个整数,代表HA至少需要联系的间谍数。如果HA不能通知到所有间谍,输出-1。

【思路】
如果是dag,就看老大能不能通知到所有入度为0的点,能的话答案就是入度为0的点个数,不能就是-1。但是可能存在环,这样即使入度不为0也要有必须通知的人,说白了就是在一个强连通分量内。所以缩点后成为dag找入度为0的点即可。 【个人感悟】
懒癌发作,拖好久了。。本来是不会写这种题的,这两天又硬着头皮学了一波tarjan。。。用并查集写虽然也ac了,然鹅数据太水了没法处理环的情况,就不贴代码了 (*/ω\*) 【ac代码】
#include <bits/stdc++.h>
using namespace std;
const int N = ;
int low[N], vis[N], dfn[N], col[N], b[N], in[N];
vector<int>V[N];
stack<int>s;
int n, cnt, num;
void dfs(int u)
{
s.push(u);
vis[u] = ;
dfn[u] = low[u] = ++cnt;
for (int i = ; i < V[u].size(); i++)
{
int v = V[u][i];
if (!dfn[v])
{
dfs(v);
low[u] = min(low[u], low[v]);
}
else if (vis[v])
low[u] = min(low[u], dfn[v]);
}
if (low[u] == dfn[u])
{
int t;
num++;
do
{
t = s.top();
s.pop();
col[t] = num;
vis[t] = ;
}
while (t != u);
}
} void tarjan()
{
int i;
memset(dfn, , sizeof(dfn));
memset(low, , sizeof(low));
memset(vis, , sizeof(vis));
memset(col, , sizeof(col));
while (!s.empty()) s.pop();
cnt = num = ;
for (i = ; i <= n; i++)
if (!dfn[i]) dfs(i);
}
int main()
{
int m, a, i, j, c;
while(~scanf("%d%d", &n, &m))
{
for(i = ; i <= n; i++) V[i].clear();
for(i = ; i <= m; i++) scanf("%d", &b[i]);
sort(b+, b++m);
for(i = ; i <= n; i++)
{
scanf("%d", &c);
while(c--)
{
scanf("%d", &a);
V[i].push_back(a);
}
}
tarjan();
for(i = ; i <= n; i++)
for(j = ; j < V[i].size(); j++)
{
int v = V[i][j];
if(col[i] != col[v]) in[col[v]]++; //缩点后入度++
}
int ans = , f = ;
for(i = ; i <= num; i++)
{
if(!in[i])
{
f = ;
for(j = ; j <= n; j++)
{
//找入度为0的强连通分量内是否包含老大能通知的点
if(col[j] == i && binary_search(b+, b++m, j))
{
ans++;
f = ;
break;
}
}
if(f == )
break;
}
}
printf("%d\n", f == ?-:ans);
}
return ;
}
 

【2018年全国多校算法寒假训练营练习比赛(第四场)- E】通知小弟(强连通缩点)的更多相关文章

  1. 【2018年全国多校算法寒假训练营练习比赛(第四场)-D】小明的挖矿之旅

    题目链接:https://www.nowcoder.com/acm/contest/76/D 做题时没注意到“无论出现在哪个格子”..题中也没说明一个格子只能经过一次,其实没有想象的复杂. 判断如果点 ...

  2. 【2018年全国多校算法寒假训练营练习比赛(第四场)-A】石油采集(匈牙利算法)

    试题链接:https://www.nowcoder.com/acm/contest/76/A [思路] 每个‘#’的右边和下边如果也是‘#’说明这两个点构成通路,以此重构一幅图,然后找二分图的最大匹配 ...

  3. 2018年全国多校算法寒假训练营练习比赛(第一场)闯关的lulu

    闯关的lulu 链接:https://www.nowcoder.com/acm/contest/67/J 来源:牛客网 题目描述 勇者lulu某天进入了一个高度10,000,000层的闯关塔,在塔里每 ...

  4. 2018年全国多校算法寒假训练营练习比赛(第一场)D N阶汉诺塔变形

    https://www.nowcoder.com/acm/contest/67/D 思路: 先手动模拟一下过程,以下是模拟过程,按顺序表示第几步需要移动的盘标号 1 1 2 1 1 2 1 1 3 1 ...

  5. 2018年全国多校算法寒假训练营练习比赛(第一场)E 恋与程序员

    https://www.nowcoder.com/acm/contest/67/E 思路: dfs 代码: #include<bits/stdc++.h> using namespace ...

  6. 2018年全国多校算法寒假训练营练习比赛(第一场)G 圆圈

    https://www.nowcoder.com/acm/contest/67/G 思路: 分形. 记录中间左边点的坐标,然后推出另外3个点的坐标,递归到最简单的情况. 代码: #include< ...

  7. 2018年全国多校算法寒假训练营练习比赛(第一场)C 六子冲

    https://www.nowcoder.com/acm/contest/67/C 思路: 模拟. 代码: #include<bits/stdc++.h> using namespace ...

  8. 2018年全国多校算法寒假训练营练习比赛(第二场)B - TaoTao要吃鸡

    链接:https://www.nowcoder.com/acm/contest/74/B来源:牛客网 题目描述 Taotao的电脑带不动绝地求生,所以taotao只能去玩pc版的荒野行动了, 和绝地求 ...

  9. 2018年全国多校算法寒假训练营练习比赛(第二场)F - 德玛西亚万岁

    链接:https://www.nowcoder.com/acm/contest/74/F来源:牛客网 题目描述 德玛西亚是一个实力雄厚.奉公守法的国家,有着功勋卓著的光荣军史. 这里非常重视正义.荣耀 ...

  10. 2018年全国多校算法寒假训练营练习比赛(第一场)J - 闯关的lulu

    链接:https://www.nowcoder.com/acm/contest/67/J来源:牛客网 题目描述 勇者lulu某天进入了一个高度10,000,000层的闯关塔,在塔里每到一层楼,他都会获 ...

随机推荐

  1. 安装RabbitMQ3.6.10报错:{error,{missing_dependencies,[crypto,ssl],

    参考https://blog.csdn.net/u010739551/article/details/80848993 如果安装上篇博文安装则可避免这种情况 CentOS6.7安装RabbitMQ3. ...

  2. python删除所有的中文字符、非ASCII或非英文字符,检查字符串是否包含非ASCII

    Your ''.join() expression is filtering, removing anything non-ASCII; you could use a conditional exp ...

  3. 数据结构&算法(一)_堆、栈(堆栈)、队列、链表

    堆: ①堆通常是一个可以被看做一棵树的数组对象.堆总是满足下列性质: ·堆中某个节点的值总是不大于或不小于其父节点的值: ·堆总是一棵完全二叉树.将根节点最大的堆叫做最大堆或大根堆,根节点最小的堆叫做 ...

  4. LeetCode:二叉树的前序遍历【144】

    LeetCode:二叉树的前序遍历[144] 题目描述 给定一个二叉树,返回它的 前序 遍历. 示例: 输入: [1,null,2,3] 1 \ 2 / 3 输出: [1,2,3] 题目分析 如果用递 ...

  5. 一个linux命令(6/13):traceroute命令

    通过traceroute 我们可以知道信息从你的计算机到互联网另一端的主机是走的什么路径.当然每次数据包由某一同样的出发点(source)到达某一同样的目的地(destination)走的路径可能会不 ...

  6. Java开发资料汇编

    Java开发常识资料   一.Java基础JSE 核心基础(程序设计语言):        <Think in java> (参考阅读:<Core Java>JAVA2核心技术 ...

  7. HDU4639

    /*计算里面有多少个相邻的he,1个he就是1种意思,两个就是,两种,所以这是 一个斐波拉期数列,间隔的hehe互不影响所以是互斥事件,直接相乘就可以*/ #include<stdio.h> ...

  8. LVS持久化

    在实际应用场景中,轮询调度并不都是适用的.有些情况下,需要我们把同一个会话的请求都调度给一个RS节点.这时候就需要LVS提供持久化的能力,能够实现会话保持. 一.LVS的持久化主要包括以下两个方面. ...

  9. python中访问限制

    在Class内部,可以有属性和方法,而外部代码可以通过直接调用实例变量的方法来操作数据,这样,就隐藏了内部的复杂逻辑. 但是,从前面Student类的定义来看,外部代码还是可以自由地修改一个实例的na ...

  10. PHP-FPM 慢执行日志、网站隔离配置

    慢执行日志 1.配置文件下打开慢执行日志 vim /usr/local/php/etc/php-fpm.conf # 慢执行日志路径 slowlog = /path/to/slow.log # 设置超 ...