当前位置: 首页 > news >正文

洛谷 - P2863 [USACO06JAN] The Cow Prom S

模板

// Problem: P2863 [USACO06JAN] The Cow Prom S
// Contest: Luogu
// URL: https://www.luogu.com.cn/problem/P2863
// Memory Limit: 128 MB
// Time Limit: 1000 ms
// 
// Powered by CP Editor (https://cpeditor.org)#include <cstdio>      // 用于输入输出函数,如scanf、printf
#include <cstring>     // 用于内存操作函数,如memset
#include <algorithm>   // 用于算法函数,如min
using namespace std;  // 引入标准命名空间,避免使用std::前缀// 定义常量:N为最大节点数,M为最大边数
const int N = 1e4 + 10, M = 1e5 + 10;int n, m;             // n表示节点数,m表示边数// 邻接表存储图:
// e[]存储边的终点,ne[]存储下一条边的索引,h[]存储表头(每个节点的第一条边索引)
// idx用于记录边的数量,作为边的唯一标识
int e[M], ne[M], h[N], idx;// Tarjan算法相关变量:
// dfn[]存储节点的深度优先搜索次序(时间戳)
// low[]存储节点能回溯到的最早时间戳
// timestamp用于记录时间戳
int dfn[N], low[N], timestamp;// 栈相关变量:
// stk[]用于存储当前路径上的节点
// top为栈顶指针
// instk[]标记节点是否在栈中
int stk[N], top;
bool instk[N];// 强连通分量(SCC)相关变量:
// scc[]存储每个节点所属的强连通分量编号
// size[]存储每个强连通分量的大小
// cnt为强连通分量的数量
int scc[N], size[N], cnt;// 向图中添加一条从a到b的有向边
// a: 起点, b: 终点
void add(int a, int b) {e[idx] = b;        // 存储边的终点ne[idx] = h[a];    // 将新边的下一条边指向当前a的第一条边h[a] = idx++;      // 更新a的第一条边为当前边,边计数加1
}// Tarjan算法核心函数,用于寻找强连通分量
// u: 当前处理的节点
void tarjan(int u) {// 初始化当前节点的dfn和low值为当前时间戳,并将时间戳加1dfn[u] = low[u] = ++timestamp;// 将当前节点入栈,并标记为在栈中stk[++top] = u;instk[u] = true;// 遍历当前节点的所有邻接边for (int i = h[u]; ~i; i = ne[i]) {  // ~i 等价于 i != -1int v = e[i];  // 获取边的终点vif (!dfn[v]) {  // 如果v未被访问过tarjan(v);  // 递归处理v// 更新当前节点的low值为其自身low值与v的low值的最小值low[u] = min(low[u], low[v]);} // 如果v已被访问且在栈中,说明形成环,更新当前节点的low值else if (instk[v]) {low[u] = min(low[u], dfn[v]);}}// 当节点u的dfn值等于low值时,说明u是一个强连通分量的根if (dfn[u] == low[u]) {cnt++;  // 强连通分量数量加1int v;  // 用于临时存储出栈的节点// 将栈中从u开始的所有节点弹出,这些节点构成一个强连通分量do {v = stk[top--];       // 栈顶节点出栈instk[v] = false;     // 标记为不在栈中scc[v] = cnt;         // 记录v所属的强连通分量编号size[cnt]++;          // 该强连通分量的大小加1} while (v != u);  // 直到弹出的节点是u为止}
}int main() {// 读取节点数和边数scanf("%d%d", &n, &m);// 初始化邻接表头为-1(表示无邻接边)memset(h, -1, sizeof h);// 读取m条边并添加到图中for (int i = 1, a, b; i <= m; i++) {scanf("%d%d", &a, &b);  // 读取边的起点a和终点badd(a, b);              // 添加边}// 对所有未访问的节点执行Tarjan算法for (int i = 1; i <= n; i++) {if (!dfn[i]) {  // 如果节点i未被访问tarjan(i);  // 处理节点i}}// 统计大小大于1的强连通分量的数量int ans = 0;for (int i = 1; i <= cnt; i++) {if (size[i] > 1) {  // 如果强连通分量i的大小大于1ans++;          // 计数加1}}// 输出结果printf("%d\n", ans);return 0;
}
http://www.sczhlp.com/news/15185/

相关文章:

  • MATLAB的地震模型构建和地震数据去噪
  • 湛江正规网站制作方案网站推广系统方案
  • 石家庄建站网页模板有哪些免费网站可以发布广告
  • 电脑版网站建设seo网络优化
  • 网站seo链接购买百度竞价返点一般多少
  • 网页制作模板如何制作娄底seo
  • 做网站销售提成怎么算网站宣传的方法有哪些
  • 语音助手理解中断问题的语义修复技术
  • redis跳表是一种数据结构,是zset有序集合的数据结构
  • centos配置静态IP
  • 衡阳电商网站建设防恶意竞价点击软件
  • 陕西哪些公司做企业网站提高工作效率的方法不正确的是
  • wordpress设置语言汕头seo不错
  • 文件上传网站源码百度搜索图片
  • 高性能网站建设 下载百度搜索官方网站
  • 网站对联代码百度学术官网
  • 乐从做网站网页设计培训学校
  • 网站建设应当注意哪些问题seo及网络推广招聘
  • 网页打不开无法访问此网站网络推广是什么职业
  • 杭州制造业企业做网站seo排名分析
  • 技术支持 东莞网站建设优化网站排名如何
  • 网站虚拟视频主持人网址查询服务器地址
  • 网站建设准备工作总结seo引擎优化是做什么的
  • Lilctf PWN方向全全全全题解!
  • 如何优雅地执行MySQL中的DDL
  • 智慧农业(特色农产品销售)
  • 减少画面抖动问题定位记录
  • 古镇小企业网站建设如何创建网站站点
  • 做网站视频用哪个视频编辑软件百度网址大全下载安装
  • 做网站用多大的画布中国疾控卫生应急服装