Acwing 1175.最大联通子图(tarjan缩点求scc)

简介: 笔记

Acwing 1175.最大连通子图


题意


1.png


输入格式

第一行包含三个整数 N , M , X  。N,M 分别表示图 G 的点数与边数,X 的意义如上文所述;

接下来 M行,每行两个正整数 a,b ,表示一条有向边(a,b) 。

图中的每个点将编号为 1 到 N ,保证输入中同一个(a,b) 不会出现两次。


输出格式

应包含两行。

第一行包含一个整数 K KK ,第二行包含整数 C   m o d   X o


数据范围


2.png


思路


3.png


强连通分量必然是半连通


求解步骤:


先用tarjan算法求出强连通分量并缩点


建图 给边判重(给边判重的原因是 两个半连通子图不相同当且仅当两个子图有某些点不同 而当两个半连通子图只有边不同时,我们认为它们相等)


拓扑图上求最大半连通子图    ⟺    \iff⟺ 求最长无分叉链


求最长无分叉链    ⟺    \iff⟺ 拓扑图上的最长路(scc中点的数量为权重)


代码

// 题目给的 M 为 1e6 但是我们要建两个图 所以 设 M 为 2e6
const int N = 1e5 + 10, M = 2e6 + 10;
int n, m, mod;
int h[N],hs[N],e[M],ne[M],idx;
int low[N],dfn[N];
int scc,timestamp;
stack<int>stk;
bool in_stk[N];
int id[N],siz[N];
int f[N],g[N];
unordered_set<LL>S;
void add(int h[],int a,int b){
  e[idx] = b,ne[idx] = h[a],h[a] = idx++;
}
void tarjan(int u){
  dfn[u] = low[u] = ++timestamp;
  stk.push(u),in_stk[u] = true;
  for(int i = h[u];~i;i = ne[i]){
    int j = e[i];
    if(!dfn[j]){
      tarjan(j);
      low[u] = min(low[u],low[j]);
    }
    else if(in_stk[j]){
      low[u] = min(low[u],dfn[j]);
    }
  }
  if(dfn[u] == low[u]){
    int y = 0;
    ++scc;
    do{
      y = stk.top();
      stk.pop();
      in_stk[y] = false;
      siz[scc]++;
      id[y] = scc;
    }while(y != u);
  }
}
void solve() {
  scanf("%d%d%d",&n,&m,&mod);
  memset(h,-1,sizeof h);
  memset(hs,-1,sizeof hs);
  while(m--){
    int a,b;scanf("%d%d",&a,&b);
    add(h,a,b);
  }
  for(int i = 1;i <= n;++i){
    if(!dfn[i])
      tarjan(i);
  }
  for(int i = 1; i <= n;++i){ // 对scc建图
    for(int j = h[i];~j;j = ne[j]){
      int k = e[j];
      int a = id[i], b = id[k];
      LL hash = a * 1000000ll + b;
      if(a != b && !S.count(hash)){
        add(hs,a,b);
        S.insert(hash);
      }
    }
  }
  for(int i = scc;i;--i){ // scc递减的顺序为 拓扑序
    if(!f[i]){
      f[i] = siz[i];
      g[i] = 1;
    }
    for(int j = hs[i];~j;j = ne[j]){
      int k = e[j];
      if(f[k] < f[i] + siz[k]){
        f[k] = f[i] + siz[k];
        g[k] = g[i];
      }
      else if(f[k] == f[i] + siz[k]){
        g[k] = (g[k] + g[i]) % mod;
      }
    }
  }
  LL sum = 0,maxn = 0;
  for(int i = 1; i <= scc;++i){
    if(f[i] > maxn){
      maxn = f[i];
      sum = g[i];
    }
    else if(f[i] == maxn){
      sum = (sum + g[i]) % mod;
    }
  }
  printf("%lld\n",maxn);
  printf("%lld\n",sum);
}
signed main() {
    //int _; cin >> _;
    //while (_--)
        solve();
    return 0;
}



目录
相关文章
|
存储
【数据结构】连通图、连通分量与强连通图、强连通分量—区别在于强,强强在哪里?
【数据结构】连通图、连通分量与强连通图、强连通分量—区别在于强,强强在哪里?
10245 1
【数据结构】连通图、连通分量与强连通图、强连通分量—区别在于强,强强在哪里?
|
4月前
|
机器学习/深度学习 人工智能 自然语言处理
38_多模态模型:CLIP的视觉-语言对齐_深度解析
想象一下,当你看到一张小狗在草地上奔跑的图片时,你的大脑立刻就能将视觉信息与"小狗"、"草地"、"奔跑"等概念联系起来。这种跨模态的理解能力对于人类来说似乎是理所当然的,但对于人工智能系统而言,实现这种能力却经历了长期的技术挑战。多模态学习的出现,标志着AI从单一模态处理向更接近人类认知方式的综合信息处理迈出了关键一步。
|
机器学习/深度学习 数据采集 TensorFlow
使用Python实现智能食品广告投放优化的深度学习模型
使用Python实现智能食品广告投放优化的深度学习模型
419 0
|
机器学习/深度学习 数据可视化 算法框架/工具
Python小项目:利用U-net完成细胞图像分割
这个项目能够锻炼你的深度学习技能,同时也能在医学、生物等领域有实际应用。你可以参考相关的教程和资源,如 GitHub 上的 U-Net 项目,以获得更详细的指导。 买CN2云服务器,免备案服务器,高防服务器,就选蓝易云。百度搜索:蓝易云
276 3
|
人工智能 自然语言处理 运维
干货|AI赋能教学开发-利用AI生成教案、课件和讲义
本文分享了高校教师利用AI工具设计课程方案和课件的经验,分为两部分。第一部分详细介绍使用GPT4o生成高质量课程大纲的过程,包括客户需求分析、提示词设计及优化调整。第二部分展示如何借助AIPPT快速制作精美课件,并介绍AIPPT的长文档解读和链接生成PPT等功能。此外,文章还分享了多个实用的AI工具、智能体和提示词技巧,助力提升教学效率与质量。
2999 3
|
机器学习/深度学习 人工智能 算法
【机器学习】RLHF:在线方法与离线算法在大模型语言模型校准中的博弈
【机器学习】RLHF:在线方法与离线算法在大模型语言模型校准中的博弈
763 6
|
算法
简单的KMP的next、nextval数组求解办法(存档自己用来复习)
简单的KMP的next、nextval数组求解办法(存档自己用来复习)
1339 2
|
机器学习/深度学习 算法 开发工具
大语言模型的直接偏好优化(DPO)对齐在PAI-QuickStart实践
阿里云的人工智能平台PAI,作为一站式的机器学习和深度学习平台,对DPO算法提供了全面的技术支持。无论是开发者还是企业客户,都可以通过PAI-QuickStart轻松实现大语言模型的DPO对齐微调。本文以阿里云最近推出的开源大型语言模型Qwen2(通义千问2)系列为例,介绍如何在PAI-QuickStart实现Qwen2的DPO算法对齐微调。
|
调度 C语言
深入浅出:C语言线程以及线程锁
线程锁的基本思想是,只有一个线程能持有锁,其他试图获取锁的线程将被阻塞,直到锁被释放。这样,锁就确保了在任何时刻,只有一个线程能够访问临界区(即需要保护的代码段或数据),从而保证了数据的完整性和一致性。 线程是操作系统能够进行运算调度的最小单位,它被包含在进程之中,是进程中的实际运作单位。一个进程可以包含一个或多个线程,而每个线程都有自己的指令指针和寄存器状态,它们共享进程的资源,如内存空间、文件句柄和网络连接等。 线程锁的概念
869 1
|
机器学习/深度学习 存储 算法
YOLOv5的Tricks | 【Trick7】指数移动平均(Exponential Moving Average,EMA)
这篇博客主要用于整理网上对EMA(指数移动平均)的介绍,在yolov5代码中也使用了这个技巧,现对其进行归纳。
2834 1
YOLOv5的Tricks | 【Trick7】指数移动平均(Exponential Moving Average,EMA)