题目链接: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. oracle入门(1)——安装oracle 11g x64 for windows

    [本文简介] 最近因为一个项目的需要,从零学习起了oracle,现在把学到的东西记录分享一下. 首先是安装篇,在win8 装10G 一直失败,网上各种方法都试过了,最后不得不放弃,选择了11G. 11 ...

  2. 1.Oracle数据库查看用户锁表和对表解锁的sql语句

    ① 查看用户锁表 select sess.sid, sess.serial#, lo.oracle_username, lo.os_user_name, ao.object_name, lo.lock ...

  3. 蛇形命名法(snake case)驼峰命名法(camel case)字符转换问题

    描述小 Hi 写程序时习惯用蛇形命名法(snake case)为变量起名字,即用下划线将单词连接起来,例如:file_name. line_number.小 Ho 写程序时习惯用驼峰命名法(camel ...

  4. Tornado模块分类

    Tornado模块分类 1. Core web framework tornado.web — 包含web框架的大部分主要功能,包含RequestHandler和Application两个重要的类 t ...

  5. Ubuntu14.04安装QT5.5

    1.进入qt目录下,修改qt安装文件属性 2:执行./qt-opensource-linux-xXXX; 3.启动Qt Creater:进入Qt5./Tools/QtCreater/bin/,可以鼠标 ...

  6. nginx缓存原理

    一.HTTP字段理解 1.Expires: 该字段的http1.0时的规范,值为一个绝对时间的GMT格式的时间字符串,代表缓存资源的过期时间,在这个时点之前即命中缓存. 缺点:服务器返回的时间,可能与 ...

  7. go——流程控制

    Go在流程控制方面的特点如下: 没有do和while循环,只有一个更广义的for语句. switch语句灵活多变,还可以用于类型判断. if语句和switch语句都可以包含一条初始化子语句. brea ...

  8. day14生成器

    生成器 我自己想写个可迭代的,——生成器生成器的本质就是迭代器因此生成器的所有好处都和迭代器一样但是生成器是我们自己写的python代码生成器的实现有两种方式:1.生成器函数2.生成器表达式 def ...

  9. delphi编程创建桌面快捷方式

    delphi编程创建桌面快捷方式   uses ActiveX,ComObj,StdCtrls,ShlObj,FileCtrl; procedure TForm1.N2Click(Sender: TO ...

  10. php debug函数

    $debug=$_GET['debug'];//是说获取url中debug变量$debug=empty($debug)?'':$debug;//如果变量不为空,赋值为$debug,为空的话赋值 ''$ ...