P2272 [ZJOI2007]最大半连通子图 tarjan+DP
思路:$tarjan+DP$
提交:1次
题解:首先对于一个强连通分量一定是一个半连通分量,并且形成的半连通分量的大小一定是它的$size$,所以我们先缩点。
这样,我们相当于要在新的$DAG$上找一个最长链(一旦有分叉边就不可能是一个半连通分量)。
于是乎写了个$dfs$,$sz[u]$表示这个(缩完后的)点的包含点的数量,$mx[u]$表示以$u$为起点最长链的长度,$tot[u]$表示方案数。
但是注意这个图有可能不连通。
#include<cstdio>
#include<iostream>
#include<map>
#define ull unsigned long long
#define ll long long
#define R register int
using namespace std;
#define pause (for(R i=1;i<=10000000000;++i))
#define In freopen("NOIPAK++.in","r",stdin)
#define Out freopen("out.out","w",stdout)
namespace Fread {
static char B[<<],*S=B,*D=B;
#ifndef JACK
#define getchar() (S==D&&(D=(S=B)+fread(B,1,1<<15,stdin),S==D)?EOF:*S++)
#endif
inline int g() {
R ret=,fix=; register char ch; while(!isdigit(ch=getchar())) fix=ch=='-'?-:fix;
if(ch==EOF) return EOF; do ret=ret*+(ch^); while(isdigit(ch=getchar())); return ret*fix;
} inline bool isempty(const char& ch) {return (ch<=||ch>=);}
inline void gs(char* s) {
register char ch; while(isempty(ch=getchar()));
do *s++=ch; while(!isempty(ch=getchar()));
}
} using Fread::g; using Fread::gs;
namespace Luitaryi {
const int N=,M=;
map<pair<int,int>,bool> mp;
int n,m,mod;
int vr[M<<],nxt[M<<],fir[M<<],cnt;
inline void add(int u,int v) {vr[++cnt]=v,nxt[cnt]=fir[u],fir[u]=cnt;}
int vv[M<<],nn[M<<],ff[M<<],ct;
inline void adde(int u,int v) {vv[++ct]=v,nn[ct]=ff[u],ff[u]=ct;}
int dfn[N],low[N],c[N],stk[N],sz[N],t[N],num,cc,top;
bool vis[N];
inline void tarjan(int u) {
dfn[u]=low[u]=++num; stk[++top]=u,vis[u]=true;
for(R i=fir[u];i;i=nxt[i]) { R v=vr[i];
if(!dfn[v]) {
tarjan(v);
low[u]=min(low[u],low[v]);
} else if(vis[v]) low[u]=min(low[u],dfn[v]);
} if(dfn[u]==low[u]) {
++cc; R tmp;
do tmp=stk[top],--top,c[tmp]=cc,++sz[cc],vis[tmp]=false; while(tmp!=u);
}
}
int anss,ans,mx[N],tot[N];
inline void dfs(int u) {
vis[u]=true; mx[u]=sz[u],tot[u]=;
for(R i=ff[u];i;i=nn[i]) { R v=vv[i];
if(!vis[v]) dfs(v);
if(sz[u]+mx[v]>mx[u]) {
mx[u]=sz[u]+mx[v];
tot[u]=tot[v];
} else if(sz[u]+mx[v]==mx[u])
tot[u]=(tot[u]+tot[v])%mod;
} ans=max(mx[u],ans);
}
inline void main() {
n=g(),m=g(),mod=g();
for(R i=,u,v;i<=m;++i) u=g(),v=g(),add(u,v);
for(R i=;i<=n;++i) if(!dfn[i]) tarjan(i);
for(R u=;u<=n;++u) for(R i=fir[u];i;i=nxt[i]) { R v=vr[i];
if(c[u]!=c[v]&&mp.find(make_pair(c[u],c[v]))==mp.end())
++t[c[v]],adde(c[u],c[v]),mp[make_pair(c[u],c[v])]=true;
} for(R i=;i<=cc;++i) if(!t[i]||!vis[i]) dfs(i);
for(R i=;i<=cc;++i) if(mx[i]==ans) anss=(anss+tot[i])%mod;
printf("%d\n%d\n",ans,anss);
}
}
signed main() {
Luitaryi::main();
return ;
}
2019.07.22
P2272 [ZJOI2007]最大半连通子图 tarjan+DP的更多相关文章
- Luogu P2272 [ZJOI2007]最大半连通子图(Tarjan+dp)
P2272 [ZJOI2007]最大半连通子图 题意 题目描述 一个有向图\(G=(V,E)\)称为半连通的\((Semi-Connected)\),如果满足:\(\forall u,v\in V\) ...
- BZOJ 1093: [ZJOI2007]最大半连通子图( tarjan + dp )
WA了好多次... 先tarjan缩点, 然后题意就是求DAG上的一条最长链. dp(u) = max{dp(v)} + totu, edge(u,v)存在. totu是scc(u)的结点数. 其实就 ...
- BZOJ1093: [ZJOI2007]最大半连通子图(tarjan dp)
题意 一个有向图G=(V,E)称为半连通的(Semi-Connected),如果满足:?u,v∈V,满足u→v或v→u,即对于图中任意两点u,v,存在一条u到v的有向路径或者从v到u的有向路径.若G' ...
- 洛谷 P2272 [ZJOI2007]最大半连通子图 解题报告
P2272 [ZJOI2007]最大半连通子图 题目描述 一个有向图\(G=(V,E)\)称为半连通的\((Semi-Connected)\),如果满足:\(\forall u,v \in V\),满 ...
- 【bzoj1093】[ZJOI2007]最大半连通子图 Tarjan+拓扑排序+dp
题目描述 一个有向图G=(V,E)称为半连通的(Semi-Connected),如果满足:对于u,v∈V,满足u→v或v→u,即对于图中任意两点u,v,存在一条u到v的有向路径或者从v到u的有向路径. ...
- [luogu2272 ZJOI2007] 最大半连通子图 (tarjan缩点 拓扑排序 dp)
传送门 题目描述 一个有向图G=(V,E)称为半连通的(Semi-Connected),如果满足:?u,v∈V,满足u→v或v→u,即对于图中任意两点u,v,存在一条u到v的有向路径或者从v到u的有向 ...
- luogu P2272 [ZJOI2007]最大半连通子图
题目描述 一个有向图G=(V,E)称为半连通的(Semi-Connected),如果满足:?u,v∈V,满足u→v或v→u,即对于图中任意两点u,v,存在一条u到v的有向路径或者从v到u的有向路径.若 ...
- [ZJOI2007]最大半连通子图 (Tarjan缩点,拓扑排序,DP)
题目链接 Solution 大概是个裸题. 可以考虑到,如果原图是一个有向无环图,那么其最大半联通子图就是最长的一条路. 于是直接 \(Tarjan\) 缩完点之后跑拓扑序 DP就好了. 同时由于是拓 ...
- BZOJ 1093 [ZJOI2007]最大半连通子图 - Tarjan 缩点
Description 定义一个半联通图为 : 对任意的两个点$u, v$,都有存在一条路径从$u$到$v$, 或从$v$到$u$. 给出一个有向图, 要求出节点最多的半联通子图, 并求出方案数. ...
随机推荐
- 使用 netkeeper 创翼网速慢解决方案(13)
1. 方法1 步骤: 卸载Netkeeper,并删除 卸载以太网(本地连接)驱动 重置网络 重启 重新安装Netkeeper.如果登录出错,卸载「IP,IPv6,Network Monitor」,然后 ...
- LC 417. Linked List Cycle II
题目描述 Given a linked list, return the node where the cycle begins. If there is no cycle, return null. ...
- python学习-28 map函数
1. num_1 = [10,2,3,4] def map_test(array): ret = [] for i in num_1: ret.append(i**2) # 列表里每个元素都平方 re ...
- 13_日期时间、Math、枚举
日期时间.Math.枚举 日期时间 计算机如何表示时间? GMT时间指格林尼治所在地的标准时间,也称为时间协调时(UTC),其他地区的时间都是相对于GMT时间的偏移. 北京位于东八区 = UTC ...
- aspnet core 全局模型验证,统一api响应
上手就来 新建一个模型验证过滤器,其中ApiResp是自定义的统一响应类. public class VldFilter:IActionFilter { /// <summary> /// ...
- SpringCloud"灰度部署"——动态刷新网关配置
通过Acutator和SpringCloudConfig完成"灰度部署"——动态刷新网关路由配置 先声明下,我这个可能是冒牌的灰度部署,技术有限,纯粹个人笔记分享. 前段时间接到了 ...
- sqlyog 如何导出建表语句
真傻了,这个问题弄了半天. 解决 点击表名后,在右侧的信息栏里面有啊: PS - 个人博客链接:sqlyog 如何导出建表语句
- 8.读写锁ReadWriteLock
/*ReadWriteLock 读写锁*/ private ReadWriteLock lock = new ReentrantReadWriteLock(); lock.readLock().loc ...
- 什么是虚拟DOM
一.前言 虚拟DOM概念随着react的诞生而诞生,由facebook提出,其卓越的性能很快得到广大开发者的认可:继react之后vue2.0也在其核心引入了虚拟DOM的概念,本文将以vue2.0使用 ...
- windows环境安装haproxy及初步配置负载均衡使用示例
安装HaProxy 首先需要下载windows环境下需要文件,这里下载的是一个别人编译好的一个文件,这里省去了编译的过程,使用的版本是haproxy-1.7.8. 下载后直接解压到对应的目录下.示例( ...