题目链接


Solution

大概是个裸题.

可以考虑到,如果原图是一个有向无环图,那么其最大半联通子图就是最长的一条路.

于是直接 \(Tarjan\) 缩完点之后跑拓扑序 DP就好了.

同时由于是拓扑序DP,要去掉所有的重边.

Code

#include<bits/stdc++.h>
#define ll long long
using namespace std;
const int maxn=100008;
struct sj{int to,next;}a[maxn*10];
ll mod,dfn[maxn],low[maxn];
ll head[maxn],belong[maxn];
ll du[maxn],w[maxn],v[maxn];
ll tot,sta[maxn],top,size,cnt;
ll num,n,m;
ll f[maxn],js[maxn],ans,ans_siz;
struct kk{int to,fr;}cc[maxn*10]; ll read()
{
char ch=getchar(); ll f=1,w=0;
while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
while(ch>='0'&&ch<='9'){w=w*10+ch-'0';ch=getchar();}
return f*w;
} void add(int x,int y)
{
a[++size].to=y;
a[size].next=head[x];
head[x]=size;
} void tarjan(int x)
{
dfn[x]=low[x]=++tot;
sta[++top]=x;
v[x]=1;
for(int i=head[x];i;i=a[i].next)
{
int tt=a[i].to;
if(!dfn[tt]){
tarjan(tt);
low[x]=min(low[x],low[tt]);
}
else if(v[tt]) low[x]=min(low[x],dfn[tt]);
}
if(dfn[x]==low[x])
{
belong[x]=++cnt;
v[x]=0;
do{
w[cnt]++;
belong[sta[top]]=cnt;
v[sta[top]]=0;
}while(sta[top--]!=x);
}
} bool cmp(kk x,kk y)
{
if(x.fr==y.fr)return x.to<y.to;
else return x.fr<y.fr;
} void work()
{
queue<int>q;
for(int i=1;i<=cnt;i++)
if(!du[i])
q.push(i),v[i]=1,f[i]=w[i],js[i]=1;
while(!q.empty())
{
int x=q.front(); q.pop();
for(int i=head[x];i;i=a[i].next)
{
int tt=a[i].to;
du[tt]--;
if(!du[tt]&&!v[tt])q.push(tt),v[tt]=1;
if(f[tt]==w[tt]+f[x])
js[tt]+=js[x],js[tt]%=mod;
if(f[tt]<w[tt]+f[x])
{
f[tt]=w[tt]+f[x];
js[tt]=js[x]%mod;
}
}
}
} int main()
{
n=read(); m=read(); mod=read();
for(int i=1;i<=m;i++)
add(read(),read());
for(int i=1;i<=n;i++)
if(!dfn[i])tarjan(i);
for(int x=1;x<=n;x++)
for(int i=head[x];i;i=a[i].next)
{
int tt=a[i].to;
if(belong[tt]!=belong[x])
cc[++num].fr=belong[x],cc[num].to=belong[tt];
}
memset(a,0,sizeof(a));
memset(head,0,sizeof(head));
size=0; sort(cc+1,cc+num+1,cmp); for(int i=1;i<=num;i++)
{
if(cc[i].fr==cc[i-1].fr&&cc[i].to==cc[i-1].to)continue;
add(cc[i].fr,cc[i].to),du[cc[i].to]++;
}
work();
for(int i=1;i<=cnt;i++)
if(f[i]>ans)
ans=f[i],ans_siz=js[i];
else if(f[i]==ans)
ans_siz+=js[i],ans_siz%=mod;
cout<<ans<<endl<<(ans_siz+mod)%mod<<endl;
return 0;
}

[ZJOI2007]最大半连通子图 (Tarjan缩点,拓扑排序,DP)的更多相关文章

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

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

  2. 2018.11.06 bzoj1093: [ZJOI2007]最大半连通子图(缩点+拓扑排序)

    传送门 先将原图缩点,缩掉之后的点权就是连通块大小. 然后用拓扑排序统计最长链数就行了. 自己yyyyyy了一下一个好一点的统计方法. 把所有缩了之后的点都连向一个虚点. 然后再跑拓扑,这样最后虚点的 ...

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

  4. BZOJ 1093 [ZJOI2007]最大半连通子图 - Tarjan 缩点

    Description 定义一个半联通图为 : 对任意的两个点$u, v$,都有存在一条路径从$u$到$v$, 或从$v$到$u$. 给出一个有向图, 要求出节点最多的半联通子图,  并求出方案数. ...

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

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

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

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

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

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

  8. BZOJ1093 ZJOI2007最大半连通子图(缩点+dp)

    发现所谓半连通子图就是缩点后的一条链之后就是个模板题了.注意缩点后的重边.写了1h+真是没什么救了. #include<iostream> #include<cstdio> # ...

  9. BZOJ1093: [ZJOI2007]最大半连通子图(tarjan dp)

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

随机推荐

  1. 换个语言学一下 Golang (3)——数据类型

    在 Go 编程语言中,数据类型用于声明函数和变量. 数据类型的出现是为了把数据分成所需内存大小不同的数据,编程的时候需要用大数据的时候才需要申请大内存,就可以充分利用内存. Go 语言按类别有以下几种 ...

  2. NPM下载模块包说明

    博主对npm包安装收集了各种资料和实践后对它们之间的差异整理,写下这篇文章避免自己忘记,同时也给node.js猿友一点指引. 我们在使用 npm install 安装模块的模块的时候 ,一般会使用下面 ...

  3. Java中的Static修饰符

    static(静态.修饰符):static修饰成员变量时:static修饰成员变量时,那么该成员变量的数据就是一个共享的数据. 静态成员变量的访问方式:方式一: 使用对象进行访问. 对象.属性名 方式 ...

  4. C++ string头文件

    转载自https://blog.csdn.net/superna666/article/details/52809007/ 作者 zhenzhenjiajia888 标准c++中string类函数介绍 ...

  5. PAT 乙级 1088

    题目 题目链接:PAT 乙级 1088 题解 比较简单的一道题,下面来简单说说思路: 因为甲确定是一个两位数,因此通过简单的暴力循环求解甲的值,又根据题设条件“把甲的能力值的 2 个数字调换位置就是乙 ...

  6. java版RSA工具类

    /** * RSA算法加密/解密工具类 */ public class RSAUtils { private static final Logger LOGGER = LoggerFactory.ge ...

  7. Linux-CentOS6.9启动流程排错

    1 . CentOS6.9启动流程 POST 加电自检,是BIOS功能的一个主要部分.负责完成对CPU.主板.内存.硬盘子系统.显示子系统.串并行接口.键盘.CD-ROM光驱等硬件情况的检测. Boo ...

  8. Yii2 HelloWord

    一.安装Yii2 可以直接官网或github下载: https://github.com/yiisoft/yii2 下载完后进入项目的web/目录,入口文件为该目录下的index.php,这里直接启用 ...

  9. python中字典的‘增、删、改、查’

    python 字典的'增.删.改.查' 用 ipython 运行情况如下: #新建字典 In [1]: infos = {'name':'dongge','age':18} In [2]: infos ...

  10. LeetCode(203) Remove LinkedList Elements

    题目 Remove all elements from a linked list of integers that have value val. Example Given: 1 –> 2 ...