热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

bzoj1093:[ZJOI2007]最大半连通子图scc缩点+dag上dp

一个有向图G(V,E)称为半连通的(Semi-Connected),如果满足:?u,v∈V,满足u→v或v→u,即对于图中任

一个有向图G=(V,E)称为半连通的(Semi-Connected),如果满足:?u,v∈V,满足u→v或v→u,即对于图中任意
两点u,v,存在一条u到v的有向路径或者从v到u的有向路径。若G'=(V',E')满足V'?V,E'是E中所有跟V'有关的边,
则称G'是G的一个导出子图。若G'是G的导出子图,且G'半连通,则称G'为G的半连通子图。若G'是G所有半连通子图
中包含节点数最多的,则称G'是G的最大半连通子图。给定一个有向图G,请求出G的最大半连通子图拥有的节点数K
,以及不同的最大半连通子图的数目C。由于C可能比较大,仅要求输出C对X的余数。

解法:把scc缩点,同一个连通分量里肯定互相可达,然后变成了dag,只需要跑一个dag上dp找最长路即可,然后需要记录一下最长路方案数,需要注意的确定点之后边就确定了,所以scc缩点时需要判一下重边

/**************************************************************Problem: 1093User: walfyLanguage: C++Result: AcceptedTime:4788 msMemory:49420 kb
***************************************************************
*///#pragma comment(linker, "/stack:200000000")
//#pragma GCC optimize("Ofast,no-stack-protector")
//#pragma GCC target("sse,sse2,sse3,ssse3,sse4,popcnt,abm,mmx,avx,tune=native")
//#pragma GCC optimize("unroll-loops")
#include
#define fi first
#define se second
#define mp make_pair
#define pb push_back
#define pi acos(-1.0)
#define ll long long
#define vi vector
#define mod 1000000007
#define C 0.5772156649
#define ls l,m,rt<<1
#define rs m&#43;1,r,rt<<1|1
#define pil pair
#define pli pair
#define pii pair
#define cd complex
#define ull unsigned long long
#define base 1000000000000000000
#define fio ios::sync_with_stdio(false);cin.tie(0)using namespace std;const double g&#61;10.0,eps&#61;1e-11;
const int N&#61;100000&#43;10,maxn&#61;1000000&#43;10,inf&#61;0x3f3f3f3f,INF&#61;0x3f3f3f3f3f3f3f3f;int n,m,X;
stack
<int>s;
vector
<int>v[N],vv[N],ans[N];
int dfn[N],low[N];
int ins[N],inans[N];
int num,ind;
int a[maxn],b[maxn];
void tarjan(int u)
{ins[u]
&#61;2;low[u]&#61;dfn[u]&#61;&#43;&#43;ind;s.push(u);for(int i&#61;0;i){int t&#61;v[u][i];if(dfn[t]&#61;&#61;0){tarjan(t);low[u]&#61;min(low[u],low[t]);}else if(ins[t]&#61;&#61;2)low[u]&#61;min(low[u],dfn[t]);}if(low[u]&#61;&#61;dfn[u]){&#43;&#43;num;while(!s.empty()){int k&#61;s.top();s.pop();ins[k]&#61;1;ans[num].push_back(k);inans[k]&#61;num;if(k&#61;&#61;u)break;}}
}
map
int>ma;
void scc()
{
for(int i&#61;1;i<&#61;n;i&#43;&#43;)if(!dfn[i])tarjan(i);for(int i&#61;0;i){int x&#61;inans[a[i]],y&#61;inans[b[i]];if(x!&#61;y&&!ma[mp(x,y)])vv[x].pb(y),ma[mp(x,y)]&#61;1;}
}
pii dp[N];
pii DP(
int u)
{
if(dp[u].fi!&#61;-1)return dp[u];dp[u].fi&#61;ans[u].size(),dp[u].se&#61;1;for(int i&#61;0;i){int x&#61;vv[u][i];pii te&#61;DP(x);if(dp[u].fians[u].size()){dp[u]&#61;te,dp[u].fi&#61;te.fi&#43;ans[u].size();
// printf("%d %d %d %d\n",u,x,dp[u].fi,dp[u].se);
}else if(dp[u].fi&#61;&#61;te.fi&#43;ans[u].size()){dp[u].se&#61;(dp[u].se&#43;te.se)%X;
// printf("%d %d %d &#43;&#43;&#43;%d\n",u,x,dp[u].se,te.se);
}}return dp[u];
}
int main()
{scanf(
"%d%d%d",&n,&m,&X);for(int i&#61;0;i){scanf("%d%d",&a[i],&b[i]);v[a[i]].pb(b[i]);}scc();memset(dp,-1,sizeof dp);for(int i&#61;1;i<&#61;n;i&#43;&#43;)DP(i);int ma&#61;0;for(int i&#61;1;i<&#61;num;i&#43;&#43;)ma&#61;max(ma,dp[i].fi);//,printf("%d %d\n",dp[i].fi,dp[i].se);int ans&#61;0;for(int i&#61;1;i<&#61;num;i&#43;&#43;)if(dp[i].fi&#61;&#61;ma)ans&#61;(ans&#43;dp[i].se)%X;printf("%d\n%d\n",ma,ans);return 0;
}
/**********************************************/

View Code

 

转:https://www.cnblogs.com/acjiumeng/p/9000610.html



推荐阅读
  • pypy 真的能让 Python 比 C 还快么?
    作者:肖恩顿来源:游戏不存在最近“pypy为什么能让python比c还快”刷屏了,原文讲的内容偏理论,干货比较少。我们可以再深入一点点,了解pypy的真相。正式开始之前,多唠叨两句 ... [详细]
  • 在1995年,Simon Plouffe 发现了一种特殊的求和方法来表示某些常数。两年后,Bailey 和 Borwein 在他们的论文中发表了这一发现,这种方法被命名为 Bailey-Borwein-Plouffe (BBP) 公式。该问题要求计算圆周率 π 的第 n 个十六进制数字。 ... [详细]
  • 问题描述现在,不管开发一个多大的系统(至少我现在的部门是这样的),都会带一个日志功能;在实际开发过程中 ... [详细]
  • 本题要求计算一组正整数的最小公倍数(LCM)。输入包括多组测试数据,每组数据首先给出一个正整数n,随后是n个正整数。 ... [详细]
  • UVa 1579 - 套娃问题
    本题主要涉及动态规划(DP)的应用,通过计算将前i个套娃合并成多个套娃组所需的最小操作次数来解决问题。具体来说,f(i) 表示前i个套娃合并成多个套娃组所需的操作次数,其计算公式为 f(i) = min(f(j) + dp(j+1, i))。 ... [详细]
  • 题目编号:2049 [SDOI2008]Cave Exploration。题目描述了一种动态图操作场景,涉及三种基本操作:断开两个节点间的连接(destroy(a,b))、建立两个节点间的连接(connect(a,b))以及查询两节点是否连通(query(a,b))。所有操作均确保图中无环存在。 ... [详细]
  • 本问题涉及在给定的无向图中寻找一个至少包含三个节点的环,该环上的节点不重复,并且环上所有边的长度之和最小。目标是找到并输出这个最小环的具体方案。 ... [详细]
  • 本文介绍如何手动实现一个字符串连接函数,该函数不依赖于C语言的标准字符串处理函数,如strcpy或strcat。函数原型为void concatenate(char *dest, char *src),其主要作用是将源字符串src追加到目标字符串dest的末尾。 ... [详细]
  • 本文详细介绍了如何在循环双链表的指定位置插入新元素的方法,包括必要的步骤和代码示例。 ... [详细]
  • 线段树详解与实现
    本文详细介绍了线段树的基本概念及其在编程竞赛中的应用,并提供了一个具体的线段树实现代码示例。 ... [详细]
  • POJ2263是一个经典的图论问题,涉及寻找从起点到终点的最大载重路径。本文将详细介绍该问题的背景、解题思路及代码实现。 ... [详细]
  • 使用QT构建基础串口辅助工具
    本文详细介绍了如何利用QT框架创建一个简易的串口助手应用程序,包括项目的建立、界面设计与编程实现、运行测试以及最终的应用程序打包。 ... [详细]
  • 本题涉及一个长度为n的序列{ai},代表一系列树木的美学价值。任务是处理m个查询,每个查询提供三个参数l、r和P,目标是在所有满足l < l' ... [详细]
  • HNOI2003 激光炸弹问题(二维前缀和的应用)难度:中等
    HNOI2003 激光炸弹问题是一个经典的二维前缀和应用题目。本文将详细介绍如何使用二维前缀和解决该问题。 ... [详细]
  • 本文介绍了一种通过设置主题(Theme)来实现快速启动的Android引导页,并详细说明了如何避免因不同屏幕分辨率导致的图片拉伸问题。 ... [详细]
author-avatar
我们的生活小窍门
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有