[ZJOI2007]最大半连通子图

题目大意:

一个有向图称为半连通的,当且仅当对于任意两点\(u,v\),都满足\(u\)能到达\(v\)或者\(v\)能到达\(u\)。

给定一个\(n(n\le10^5)\)个点,\(m(m\le10^6)\)条边的有向图,

问该图最大半连通子图的节点个数及方案数。

思路:

缩点后在DAG上DP求带点权最长链,并统计方案数即可。

源代码:

#include<stack>
#include<queue>
#include<cstdio>
#include<cctype>
#include<vector>
#include<algorithm>
inline int getint() {
register char ch;
while(!isdigit(ch=getchar()));
register int x=ch^'0';
while(isdigit(ch=getchar())) x=(((x<<2)+x)<<1)+(ch^'0');
return x;
}
const int N=1e5+1,M=1e6;
std::pair<int,int> edge[M];
std::vector<int> e[N];
std::stack<int> s;
bool ins[N];
int n,m,mod,dfn[N],low[N],scc[N],ind[N],f[N],g[N],size[N];
inline void add_edge(const int &u,const int &v) {
e[u].push_back(v);
}
void tarjan(const int &x) {
s.push(x);
ins[x]=true;
low[x]=dfn[x]=++dfn[0];
for(unsigned i=0;i<e[x].size();i++) {
const int &y=e[x][i];
if(!dfn[y]) {
tarjan(y);
low[x]=std::min(low[x],low[y]);
} else if(ins[y]) {
low[x]=std::min(low[x],dfn[y]);
}
}
if(dfn[x]==low[x]) {
scc[0]++;
for(register int y=0;y!=x;s.pop()) {
ins[y=s.top()]=false;
size[scc[y]=scc[0]]++;
}
}
}
std::queue<int> q;
void kahn() {
for(register int i=1;i<=scc[0];i++) {
if(ind[i]==0) {
q.push(i);
f[i]=size[i];
g[i]=1;
}
}
while(!q.empty()) {
const int &x=q.front();
for(unsigned i=0;i<e[x].size();i++) {
const int &y=e[x][i];
if(f[x]+size[y]>f[y]) {
f[y]=f[x]+size[y];
g[y]=0;
}
if(f[y]==f[x]+size[y]) (g[y]+=g[x])%=mod;
if(--ind[y]==0) q.push(y);
}
q.pop();
}
}
int main() {
n=getint(),m=getint(),mod=getint();
for(register int i=0;i<m;i++) {
const int u=getint(),v=getint();
edge[i]=std::make_pair(u,v);
add_edge(u,v);
}
for(register int i=1;i<=n;i++) {
if(!dfn[i]) tarjan(i);
}
for(register int i=1;i<=n;i++) {
e[i].clear();
}
for(register int i=0;i<m;i++) {
edge[i].first=scc[edge[i].first];
edge[i].second=scc[edge[i].second];
}
std::sort(&edge[0],&edge[m]);
m=std::unique(&edge[0],&edge[m])-edge;
for(register int i=0;i<m;i++) {
if(edge[i].first==edge[i].second) continue;
add_edge(edge[i].first,edge[i].second);
ind[edge[i].second]++;
}
kahn();
int ans=0,cnt=0;
for(register int i=1;i<=scc[0];i++) {
if(f[i]>ans) {
ans=f[i];
cnt=0;
}
if(f[i]==ans) (cnt+=g[i])%=mod;
}
printf("%d\n%d\n",ans,cnt);
return 0;
}

[ZJOI2007]最大半连通子图的更多相关文章

  1. BZOJ 1093 [ZJOI2007] 最大半连通子图(强联通缩点+DP)

    题目大意 题目是图片形式的,就简要说下题意算了 一个有向图 G=(V, E) 称为半连通的(Semi-Connected),如果满足图中任意两点 u v,存在一条从 u 到 v 的路径或者从 v 到 ...

  2. BZOJ 1093 [ZJOI2007]最大半连通子图

    1093: [ZJOI2007]最大半连通子图 Time Limit: 30 Sec  Memory Limit: 162 MBSubmit: 1986  Solved: 802[Submit][St ...

  3. bzoj 1093 [ZJOI2007]最大半连通子图(scc+DP)

    1093: [ZJOI2007]最大半连通子图 Time Limit: 30 Sec  Memory Limit: 162 MBSubmit: 2286  Solved: 897[Submit][St ...

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

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

  5. 洛谷 P2272 [ZJOI2007]最大半连通子图 解题报告

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

  6. 题解 P2272 【[ZJOI2007]最大半连通子图】

    P2272 [ZJOI2007]最大半连通子图 萌新初学Tarjan,在<信息学奥赛一本通-提高篇>中看到这题,看到题解不多,便想发布一篇较为清新简洁的题解.--第5道紫题 题目大意: 定 ...

  7. [ZJOI2007]最大半连通子图(Tarjan,拓扑序DP)

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

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

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

  9. BZOJ1093 [ZJOI2007]最大半连通子图

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

随机推荐

  1. 【洛谷 P1502】 窗口的星星(扫描线)

    题目链接 把每个星星作为左下角,做出长为\(w-0.5\),宽为\(h-0.5\)的矩形. \(-0.5\)是因为边框上的不算. 离散化\(y\)坐标. 记录\(2n\)个\(4\)元组\((x,y1 ...

  2. U盘出现大量乱码文件,并且不能彻底删除

    问题如图所示: 问题出现原因:不正常的插拔等情况造成的,导致U盘的文件分配表错乱了 解决方法:参考http://bbs.cfanclub.net/thread-405004-1-1.html 运行ch ...

  3. laravel学习教程整理

    百度传课:https://chuanke.baidu.com/v5847462-219167-1421398.html

  4. VueJS 轻松支持 JSX 配置

    使用: babel-preset-vue-app TODO

  5. 配置tomcat多域名访问

    C:\Windows\System32\drivers\etc下的hosts文件改成:127.0.0.1 localhost 127.0.0.1 www.greenmood.net 127.0.0.1 ...

  6. Linux kernel kfifo分析【转】

    转自:https://zohead.com/archives/linux-kernel-kfifo/ 本文同步自(如浏览不正常请点击跳转):https://zohead.com/archives/li ...

  7. 《secret》读书笔记

    这是在从大连到深圳飞机上看完的一本书,也是大学毕业时室友整理书籍给我的.正好回来的途中,一气呵成读完了. 全书讲了几个事情,其中费了很大篇幅就围绕一个主题,当然书题了——秘密,这个秘密就是“吸引力法则 ...

  8. 20行js代码制作网页刮刮乐

    分享一段用canvas和JS制作刮刮乐的代码,JS部分去掉注释不到20行代码效果如下 盖伦.jpg 刮刮乐.gif HTML部分 <body> ![](img/gailun.jpg) &l ...

  9. cordova 从xcode7迁移到xcode8

    环境以开发流程 当前项目使用的cordova环境 cordova 6.1.1 cordova-ios 3.9.2(vs15自动装的不知道在哪能改,所以考虑升级到vs17,能够手动指定) cordova ...

  10. /etc/issue 与 /etc/issue.net 文件,telnet登陆前的显示

    在使用文本设备(关于文本设备的例子,见下面的说明)登录Linux系统之前,系统会显示一条被称作“issue”的消息: 若是通过本地文本设备(如本地终端,本地虚拟控制台等)登录,则该信息存放与/etc/ ...