题目链接


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. ctrl+shift+f

    ctrl+f是在当前文件寻找某个参数 ctrl+shift+f是在整个工程目录下寻找某个参数

  2. c#中接口、抽象类、继承综合小练习

    namespace Test { class Program { static void Main(string[] args) { //作业:橡皮rubber鸭子.木wood鸭子.真实的鸭子real ...

  3. Bootstrap历练实例:带徽章的列表组

    向列表组添加徽章 我们可以向任意的列表项添加徽章组件,它会自动定位到右边.只需要在 <li> 元素中添加 <span class="badge"> 即可.下 ...

  4. OC和C++的混用1

    //Objective-C类 /*在混用之前需要做一步非常重要的事:不是代码而是编译器选项,在做混合编译之前一定要把编译器的Compile Sources As选项改为Objective C++. 修 ...

  5. ES6 -- 模板字符串(反单引号)

    1)直接使用变量 // before var str = 'test'; console.log(str + "123"); // now var str = 'test'; co ...

  6. [图文]RHEL 7/CentOS 7/Fedora28 联网初始化

    实验说明: 入门Linux,一般会遇到以下几个问题: 从哪里获取LInux镜像? 如何通过镜像文件安装Linux系统? 安装实体机还是虚拟机? 安装完系统如何配置网络? 虚拟机的网络配置与实体机有何不 ...

  7. windows charles 抓包https请求

    charles证书     2.设置host和端口 3.浏览器访问即可抓到https的请求  

  8. ccf 201712-3 Crontab(Python实现)

    一.原题 问题描述 试题编号: 201712-3 试题名称: Crontab 时间限制: 10.0s 内存限制: 256.0MB 问题描述: 样例输入 3 201711170032 201711222 ...

  9. paper:synthesizable finit state machine design techniques using the new systemverilog 3.0 enhancements之onehot coding styles(encoded-parameter style with registered outputs不推荐但是经常有人写这样的代码)

    这样写法,不利与综合,case语句中比较也是full-vector比较.

  10. 《Java并发编程实战》读书笔记一 -- 简介

    <Java并发编程实战>读书笔记一 -- 简介 并发的历史 并发的历史,也是人类利用有限的资源去提高生产效率的一个的例子. 设想现在有台计算机,这台计算机具有以下的资源: 单核CPU一个 ...