题意

一个有向图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的余数。

Sol

很zz的题然而我因为没判重边的缘故wa了好久qwq

首先强连通分量内的点一定是半联通图

如果任意链各个强连通分量之间有边的话,它们构成的图是半联通图

那么我们最长路dp一下就好,同时dp出方案数。

#include<cstdio>
#include<algorithm>
#include<stack>
#include<queue>
#define Pair pair<int, int>
#define fi first
#define se second
#define MP(x, y) make_pair(x, y)
//#define int long long
using namespace std;
const int MAXN = * 1e5 + ;
inline int read() {
char c = getchar(); int x = , f = ;
while(c < '' || c > '') {if(c == '-') f = -; c = getchar();}
while(c >= '' && c <= '') x = x * + c - '', c = getchar();
return x * f;
}
int N, M, mod;
vector<int> v[MAXN], E[MAXN];
int low[MAXN], dfn[MAXN], col[MAXN], vis[MAXN], tot, cn, f[MAXN], g[MAXN], inder[MAXN], siz[MAXN], fuck[MAXN];
stack<int> s;
void tarjan(int x) {
low[x] = dfn[x] = ++tot;
vis[x] = ; s.push(x);
for(int i = ; i < v[x].size(); i++) {
int to = v[x][i];
if(!dfn[to]) tarjan(to), low[x] = min(low[x], low[to]);
else if(vis[to]) low[x] = min(low[x], dfn[to]);
}
if(dfn[x] == low[x]) {
int h; cn++;
do {
h = s.top(); s.pop();
col[h] = cn; vis[h] = ;
siz[cn]++;
}while(x != h);
}
}
void Topsort() {
queue<int> q;
for(int i = ; i <= cn; i++) {
if(!inder[i]) q.push(i);
f[i] = siz[i], g[i] = ;
}
Pair ans = MP(, );
while(!q.empty()) {
int p = q.front(); q.pop();
for(int i = ; i < E[p].size(); i++) {
int to = E[p][i], val = f[p] + siz[to];
inder[to]--;
if(!inder[to]) q.push(to);
if(fuck[to] == p) continue;
if(f[to] == val) (g[to] += g[p]) %= mod;
else if(val > f[to]) f[to] = val, g[to] = g[p] % mod;
fuck[to] = p;
}
}
for(int i = ; i <= cn; i++)
if(f[i] > ans.fi)
ans.fi = f[i];
for(int i = ; i <= cn; i++)
if(f[i] == ans.fi)
ans.se = (ans.se + g[i]) % mod;
printf("%d\n%d", ans.fi, ans.se % mod);
}
main() {
// freopen("3.in", "r", stdin);
N = read(); M = read(); mod = read();
for(int i = ; i <= M; i++) {
int x = read(), y = read();
v[x].push_back(y);
}
for(int i = ; i <= N; i++)
if(!dfn[i]) tarjan(i);
for(int x = ; x <= N; x++) {
// sort(v[x].begin(), v[x].end(), comp);
// int last = -1;
for(int i = ; i < v[x].size(); i++) {
int to = v[x][i];
// if(i > 0 && (col[to] == col[last])) continue;
if(col[x] != col[to])
E[col[x]].push_back(col[to]), inder[col[to]]++;
// last = to;
}
}
Topsort();
return ;
}
/*
*/

BZOJ1093: [ZJOI2007]最大半连通子图(tarjan dp)的更多相关文章

  1. BZOJ 1093: [ZJOI2007]最大半连通子图( tarjan + dp )

    WA了好多次... 先tarjan缩点, 然后题意就是求DAG上的一条最长链. dp(u) = max{dp(v)} + totu, edge(u,v)存在. totu是scc(u)的结点数. 其实就 ...

  2. Luogu P2272 [ZJOI2007]最大半连通子图(Tarjan+dp)

    P2272 [ZJOI2007]最大半连通子图 题意 题目描述 一个有向图\(G=(V,E)\)称为半连通的\((Semi-Connected)\),如果满足:\(\forall u,v\in V\) ...

  3. P2272 [ZJOI2007]最大半连通子图 tarjan+DP

    思路:$tarjan+DP$ 提交:1次 题解:首先对于一个强连通分量一定是一个半连通分量,并且形成的半连通分量的大小一定是它的$size$,所以我们先缩点. 这样,我们相当于要在新的$DAG$上找一 ...

  4. bzoj1093[ZJOI2007]最大半连通子图(tarjan+拓扑排序+dp)

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

  5. 【bzoj1093】[ZJOI2007]最大半连通子图 Tarjan+拓扑排序+dp

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

  6. 【tarjan 拓扑排序 dp】bzoj1093: [ZJOI2007]最大半连通子图

    思维难度不大,关键考代码实现能力.一些细节还是很妙的. Description 一个有向图G=(V,E)称为半连通的(Semi-Connected),如果满足:?u,v∈V,满足u→v或v→u,即对于 ...

  7. 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 ...

  8. [luogu2272 ZJOI2007] 最大半连通子图 (tarjan缩点 拓扑排序 dp)

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

  9. BZOJ1093 [ZJOI2007]最大半连通子图 【tarjan缩点 + DAG最长路计数】

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

随机推荐

  1. Proxy模式(代理[延迟]模式)

    Proxy?? Proxy是"代理人"的意思,它指的是代替别人进行工作的人.代理实际上就是使用委托的机制,在代理的过程中你可以做点其他的事情,然后再来执行被代理对象的代码. 知识储 ...

  2. Gradle 安装(Windows)

    一.Gradle 简介 1.1 什么是 Gradle?   Gradle 是一个基于 Apache Ant 和 Apache Maven 概念的 项目自动化构建开源工具.它使用一种基于Groovy的D ...

  3. web应用,http协议简介,web框架

    一.web应用 web应用程序是一种可以通过Web访问的应用程序,程序的最大好处是用户很容易访问应用程序,用户只需要有浏览器即可,不需要再安装其他软件.应用程序有两种模式C/S.B/S.C/S是客户端 ...

  4. chapter09

    import java.io.File import java.nio.file._ import scala.collection.mutable.ArrayBuffer/** * Created ...

  5. 02-----body签中相关标签

    大纲 字体标签: h1~h6.<font>.<u>.<b>.<strong><em>.<sup>.<sub> 排版标 ...

  6. vector的学习

    学习链接:http://www.runoob.com/cplusplus/cpp-stl-tutorial.html kandaima #include<iostream> #includ ...

  7. 三节点Hadoop集群搭建

    1. 基础环境搭建 新建3个CentOS6.5操作系统的虚拟机,命名(可自定)为masternode.slavenode1和slavenode2.该过程参考上一篇博文CentOS6.5安装配置详解 2 ...

  8. SpringBoot2.0之三 优雅整合Spring Data JPA

      在我们的实际开发的过程中,无论多复杂的业务逻辑到达持久层都回归到了"增删改查"的基本操作,可能会存在关联多张表的复杂sql,但是对于单表的"增删改查"也是不 ...

  9. 北航oo作业第三单元小结

    一.梳理JML语言的理论基础 1.jml的注释结构 jml注释语言的每一行都以@作为开始,若是块注释,则需要在注释块的首尾使用/*@ 与@*/ 2.jml的表达式体系 1.原子表达式 表达式可以看作是 ...

  10. 映射部署tomcat

    近期遇到问题总结[映射部署]2017年10月03日 10:16:54 守望dfdfdf 阅读数:108更多个人分类: Java知识编辑版权声明:本文为博主原创文章,转载请注明文章链接. https:/ ...