缩点后在一个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. Insomni’hack CTF-l33t-hoster复现分析

    题目地址: https://github.com/eboda/insomnihack/tree/master/l33t_hoster 源码如下: <?php if (isset($_GET[&q ...

  2. 最新 猎豹移动java校招面经 (含整理过的面试题大全)

    从6月到10月,经过4个月努力和坚持,自己有幸拿到了网易雷火.京东.去哪儿.猎豹移动等10家互联网公司的校招Offer,因为某些自身原因最终选择了猎豹移动.6.7月主要是做系统复习.项目复盘.Leet ...

  3. 带你手写基于 Spring 的可插拔式 RPC 框架(四)代理类的注入与服务启动

    上一章节我们已经实现了从客户端往服务端发送数据并且通过反射方法调用服务端的实现类最后返回给客户端的底层协议. 这一章节我们来实现客户端代理类的注入. 承接上一章,我们实现了多个底层协议,procoto ...

  4. c++ hex string array 转换 串口常用

    c++ hex string array 转换 效果如下 tset string is follow 0x50 55 0x35 00 10 203040506073031323334ff format ...

  5. 通过DLNA将电脑视频投射到电视屏幕

    1. DLNA DLNA(Digital Living Network Alliance)是由索尼.英特尔.微软等发起成立的一套解决电脑.移动设备.消费电器之间互联互通的协议.它们的宗旨是“随时随地享 ...

  6. 微信小程序的calc不生效处理

    大致文字初略的记录描述一下问题:外层是relative相对定位,内部一个view 需要绝对定位bottom的值为128rpx,同时还要兼容适配苹果x的底部,所以值是这样设置的: bottom: cal ...

  7. [转帖]关于USB3.0以及type-C

    忘记来源页面了.. 但是昨天晚上 usb 4.0 发布了 跟雷电C 安全一样的标准 双向40gb 的带宽. 而且 以后只有usb type-C的接口了. 我们办公机器上面的 typeC 同事用 ngf ...

  8. java中JDBC是什么?

    [学习笔记] JDBC是什么? JDBC即(java database connectivity数据连接).JDBC是Sun公司编的一堆类和方法,都封装在java.sql包中.你可以利用这堆类和方法来 ...

  9. 【Python基础】14_Python中的TODO注释

    # TODO XXX... IDE中右键左下角,可显示当前项目所有的TODO

  10. Wannafly挑战赛22

    B. 字符路径 给一个含n个点m条边的有向无环图(允许重边,点用1到n的整数表示),每条边上有一个字符,问图上有几条路径满足路径上经过的边上的字符组成的的字符串去掉空格后以大写字母开头,句号 '.' ...