2018年全国多校算法寒假训练营练习比赛(第四场)-E-通知小弟【强联通】

题意:
第一行:n个点 m组数据
第二行:HA能通知到的人
第三行——最后一行(1———n):【第一个字表示有几个能通知到的】
思路:
强联通分量个数
缩点后处理
输入
3 2
1 2
1 2
1 1
0
输出
-1
输入
3 1
1
2 2 3
0
0
输出
1

#include
#include
#include
#include
#include
using namespace std;

#define MAXN 505

int n,m;
///dfn记录节点的被访问时间(时间戳)
///low记录该点或者以这个点为根的子树能够追溯到最早的栈中节点的次序
int dfn[MAXN],low[MAXN];
///vis标记是否在栈中,num为每个强连通分量的节点数,belong标记节点属于第几个强连通分量
int vis[MAXN],num[MAXN],belong[MAXN];
int cnt,idx; ///cnt为强连通分量的个数,idx为节点访问的编号(每个节点不同)
stack s;
vector map[MAXN];

void tarjan(int u)
{
    int i,v;
    dfn[u]=low[u]=++idx; ///新点初始化
    s.push(u); ///入栈
    vis[u]=1;  ///标记在栈中
    for(i=0; i mp[MAXN];   ///由所有强连通分量形成的新图
int ru[MAXN]; //入度

void suodian(int n)
{
    ///缩点函数,其中n为节点个数
    int i,j,u,v;
    memset(ru,0,sizeof(ru));
    for(i=1; i<=n; i++) mp[i].clear();
    for(i=1; i<=n; i++)
    {
        ///扫描每个节点
        u=belong[i];   ///原来起点所在的强连通分量
        for(j=0; j

你可能感兴趣的:(牛客网)