缩点后在一个DAG上求最长点权链 和方案数

注意转移条件和转移状态

            if (nowmaxn[x] > nowmaxn[v]) {
ans[v] = ans[x];
nowmaxn[v] = nowmaxn[x];
} else if (nowmaxn[x] == nowmaxn[v]) {
ans[v] = (ans[v] + ans[x]) % X;
}
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int MAXN = ;
const int MAXM = ;
int deep, colorsum = ;
int top;/*sta目前的大小*/
int dfn[MAXN], color[MAXN], low[MAXN];
int sta[MAXN];//存着当前所有可能能构成强连通分量的点
bool visit[MAXN];//表示一个点目前是否在sta中
int cnt[MAXN];//各个强连通分量中含点的数目
int to[MAXM << ], nxt[MAXM << ], Head[MAXN], ed = ;
inline void addedge(int u, int v)
{
to[++ed] = v;
nxt[ed] = Head[u];
Head[u] = ed;
}
void tarjan(int x)
{
dfn[x] = ++deep;
low[x] = deep;
visit[x] = ;
sta[++top] = x;
for (int i = Head[x]; i; i = nxt[i]) {
int v = to[i];
if (!dfn[v]) {
tarjan(v);
low[x] = min(low[x], low[v]);
} else {
if (visit[v]) {
low[x] = min(low[x], low[v]);
}
}
}
if (dfn[x] == low[x]) {
color[x] = ++colorsum;
visit[x] = ;
while (sta[top] != x) {
color[sta[top]] = colorsum;
visit[sta[top--]] = ;
}
top--;
}
}
int X;
int du[MAXN];
vector<int> g[MAXN];
map<pair<int, int>, int> mp, mp2;
queue<int> que;
int ans[MAXN];
int nowmaxn[MAXN];
int main()
{
int n, m;
int u, v;
scanf("%d %d %d", &n, &m, &X);
for (int i = ; i <= m; i++) {
scanf("%d %d", &u, &v);
if (!mp2[make_pair(u, v)]) {
addedge(u, v);
mp2[make_pair(u, v)] = ;
}
}
for (int i = ; i <= n; i++) {
if (!dfn[i]) {
tarjan(i);
}
cnt[color[i]]++;
}
for (u = ; u <= n; u++) {
int x = color[u];
for (int i = Head[u]; i; i = nxt[i]) {
v = to[i];
int y = color[v];
if (x != y) {
if (!mp[make_pair(x, y)]) {
g[x].push_back(y);
du[y]++;
mp[make_pair(x, y)] = ;
}
}
}
}
for (int i = ; i <= colorsum; i++) {
if (du[i] == ) {
que.push(i);
ans[i] = ;
}
}
while (que.size()) {
int x = que.front();
que.pop();
nowmaxn[x] += cnt[x];
for (int i = ; i < g[x].size(); i++) {
v = g[x][i];
if (nowmaxn[x] > nowmaxn[v]) {
ans[v] = ans[x];
nowmaxn[v] = nowmaxn[x];
} else if (nowmaxn[x] == nowmaxn[v]) {
ans[v] = (ans[v] + ans[x]) % X;
}
du[v]--;
if (du[v] == ) {
que.push(v);
}
}
}
int anser = ;
int maxnn = ;
for (int i = ; i <= colorsum; i++) {
if (nowmaxn[i] > maxnn) {
anser = ans[i];
maxnn = nowmaxn[i];
} else if (nowmaxn[i] == maxnn) {
anser = (anser + ans[i]) % X;
}
}
cout << maxnn << endl;
cout << anser << endl; }

BZOJ 1093 强连通缩点+DAG拓扑DP的更多相关文章

  1. UVA 11324 The Largest Clique(强连通分量+缩点DAG的DP)

    题意:给定一个有向图,求出一个最大的结点集,这个节点集中的随意两个点之间至少一个能到达还有一个点. 思路:假设一个点在这个节点集中,那么它所在的强连通分量中的点一定所有在这个节点集中,反之亦然, 求出 ...

  2. BZOJ 5450 轰炸 (强连通缩点+DAG最长路)

    <题目链接> 题目大意: 有n座城市,城市之间建立了m条有向的地下通道.你需要发起若干轮轰炸,每轮可以轰炸任意多个城市.但每次轰炸的城市中,不能存在两个不同的城市i,j满足可以通过地道从城 ...

  3. bzoj1179: [Apio2009]Atm scc缩点+dag上dp

    先把强连通缩点,然后变成了dag,dp求终点是酒吧的最长路即可, /************************************************************** Pro ...

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

    一个有向图G=(V,E)称为半连通的(Semi-Connected),如果满足:?u,v∈V,满足u→v或v→u,即对于图中任意两点u,v,存在一条u到v的有向路径或者从v到u的有向路径.若G'=(V ...

  5. Tarjan缩点+DAG图dp

    题目背景 缩点+DP 题目描述 给定一个n个点m条边有向图,每个点有一个权值,求一条路径,使路径经过的点权值之和最大.你只需要求出这个权值和. 允许多次经过一条边或者一个点,但是,重复经过的点,权值只 ...

  6. UVA - 11324 The Largest Clique 强连通缩点+记忆化dp

    题目要求一个最大的弱联通图. 首先对于原图进行强连通缩点,得到新图,这个新图呈链状,类似树结构. 对新图进行记忆化dp,求一条权值最长的链,每一个点的权值就是当前强连通分量点的个数. /* Tarja ...

  7. BZOJ5017 [Snoi2017]炸弹[线段树优化建边+scc缩点+DAG上DP/线性递推]

    方法一: 朴素思路:果断建图,每次二分出一个区间然后要向这个区间每个点连有向边,然后一个环的话是可以互相引爆的,缩点之后就是一个DAG,求每个点出发有多少可达点. 然后注意两个问题: 上述建边显然$n ...

  8. POJ 1236 学校传数据 强连通+缩点+DAG

    题意描述: 网络中有一些学校,每个学校可以分发软件给其他学校.可以向哪个分发取决于他们各自维护的一个清单. 两个问题 1:至少要copy多少份新软件给那些学校, 才能使得每个学校都能得到. 2:要在所 ...

  9. [模板][Luogu3387] 缩点 - Tarjan, 拓扑+DP

    Description 给定一个n个点m条边有向图,每个点有一个权值,求一条路径,使路径经过的点权值之和最大.你只需要求出这个权值和. 允许多次经过一条边或者一个点,但是,重复经过的点,权值只计算一次 ...

随机推荐

  1. go语言简单介绍,增强了解

    1. Go语言没有类和继承的概念,所以它和 Java 或 C++ 看起来并不相同.但是它通过接口(interface)的概念来实现多态性.Go语言有一个清晰易懂的轻量级类型系统,在类型之间也没有层级之 ...

  2. JavaScript 检测值

    了解常见的真值和假值,可以增强判断能力.在使用if判断时,提升编码速度. 了解常见的检测和存在,一样可以增强判断能力,而且是必须掌握的. 数组和对象被视为真值 1 2 3 4 5 6 7 8 9 10 ...

  3. MySQL中的触发器应用

    直接上代码: /*数据库 - udi_ems_test*********************************************************************内容:在 ...

  4. Windows32或64位下载安装配置Spark

    [学习笔记] Windows 32或64位下载安装配置Spark:1)下载地址:http://spark.apache.org/downloads.html 马克-to-win @ 马克java社区: ...

  5. (二)mybatis框架原理(图解)

    目录 mybatis 框架原理图(粗略版) mybatis 框架原理图(粗略版)

  6. python学习-10 运算符1

    1.加+,减-,乘*,除/ 例如: a = 1 b = 2 c = a + b print(c) 运算结果: 3 Process finished with exit code 0 a = 1 b = ...

  7. 测试工作小工具~总结&下载连接

    1.Gif录制小工具(动图提单 ≖ᴗ≖) 地址:https://licecap.en.softonic.com/download

  8. varnish CLI管理

    命令:varnishadm [-t timeout] [-S secret_file] [-T address:port] [-n name] [command [...]] ./varnishadm ...

  9. k8s之dashboard认证、资源需求、资源限制及HeapSter

    1.部署dashboard kubernetes-dashboard运行时需要有sa账号提供权限 Dashboard官方地址:https://github.com/kubernetes/dashboa ...

  10. 数据库优化SQL

    sql优化规则: 1.对于查询,尽量不要使用全表扫描,尽量在where子句以及order by所对应的字段建立索引. 2.应尽量避免在 where 子句中对字段进行 null 值判断,否则将导致引擎放 ...