题目:https://www.lydsy.com/JudgeOnline/problem.php?id=1093

先缩点,然后就是找最长链,DP一下即可;

注意缩点后的重边!会导致重复计算答案。

代码如下:

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
typedef long long ll;
int const maxn=1e5+,maxm=1e6+;
int n,m,mod,hd[maxn],ct,col[maxn],cr,tim,dfn[maxn],low[maxn],sta[maxn],top,h,t;
int f[maxn],s[maxn],siz[maxn],deg[maxn],ans,mk[maxn];
ll cnt;
bool vis[maxn];
struct N{
int fr,to,nxt;
N(int f=,int t=,int n=):fr(f),to(t),nxt(n) {}
}ed[maxm];
void add(int x,int y){ed[++ct]=N(x,y,hd[x]); hd[x]=ct;}
//void add2(int x,int y){edge[++xt]=N(y,head[x]); head[x]=xt;}
int rd()
{
int ret=,f=; char ch=getchar();
while(ch<''||ch>''){if(ch=='-')f=-; ch=getchar();}
while(ch>=''&&ch<='')ret=ret*+ch-'',ch=getchar();
return ret*f;
}
void tarjan(int x)
{
dfn[x]=low[x]=++tim;
sta[++top]=x; vis[x]=;
for(int i=hd[x],u;i;i=ed[i].nxt)
{
if(!dfn[u=ed[i].to])tarjan(u),low[x]=min(low[x],low[u]);
else if(vis[u])low[x]=min(low[x],dfn[u]);
}
if(low[x]==dfn[x])
{
cr++; int y;
while((y=sta[top])!=x)col[y]=cr,vis[y]=,siz[cr]++,top--;
col[x]=cr; vis[x]=; siz[cr]++; top--;
}
}
void topo()
{
// for(int i=1;i<=cr;i++)
// if(!deg[i])q.push(i),f[i]=siz[i],s[i]=1;
h=; t=;
for(int i=;i<=cr;i++)
if(!deg[i])sta[++t]=i,f[i]=siz[i],s[i]=;
while(h<=t)
{
// int x=q.front(); q.pop();
int x=sta[h]; h++;
for(int i=hd[x],u;i;i=ed[i].nxt)
{
deg[u=ed[i].to]--; if(!deg[u])sta[++t]=u;//
if(mk[u]==x)continue;//注意处理连通块之间的重边!
if(f[u]<f[x]+siz[u])f[u]=f[x]+siz[u],s[u]=s[x];
else if(f[u]==f[x]+siz[u])s[u]=(s[u]+s[x])%mod;
mk[u]=x;
}
}
}
int main()
{
n=rd(); m=rd(); mod=rd();
for(int i=,x,y;i<=m;i++)
{
x=rd(); y=rd();
add(x,y);
}
for(int i=;i<=n;i++)
if(!dfn[i])tarjan(i);
ct=; memset(hd,,sizeof hd);
for(int i=;i<=m;i++)
{
int u=ed[i].fr,v=ed[i].to;
if(col[u]==col[v])continue;
add(col[u],col[v]); deg[col[v]]++;
}
// for(int i=1;i<=n;i++)
// for(int j=hd[i],u;j;j=ed[j].nxt)
// {
// if(col[i]==col[u=ed[j].to])continue;
// add2(col[i],col[u]); deg[col[u]]++;
// }
topo();
for(int i=;i<=cr;i++)
{
if(f[i]>ans)ans=f[i],cnt=s[i];
else if(f[i]==ans)(cnt+=s[i])%=mod;
}
printf("%d\n%lld\n",ans,cnt);
return ;
}

bzoj 1093 [ ZJOI 2007 ] 最大半连通子图 —— 拓扑+DP的更多相关文章

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

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

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

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

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

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

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

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

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

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

  6. bzoj 1093 最大半连通子图 - Tarjan - 拓扑排序 - 动态规划

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

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

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

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

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

  9. BZOJ 1093 最大半连通子图 题解

    1093: [ZJOI2007]最大半连通子图 Time Limit: 30 Sec  Memory Limit: 162 MBSubmit: 2767  Solved: 1095[Submit][S ...

随机推荐

  1. Oracle、Db2、SqlServer、MySQL 数据库插入当前系统时间

    做易买网项目,由于对数据库插入系统时间不了解,常常遇到的问题: 1.java.sql.SQLException: ORA-01861: 文字与格式字符串不匹配.原因:由于获取系统时间类型不对,应为sy ...

  2. CNN-CV识别简史2012-2017:从 AlexNet、ResNet 到 Mask RCNN

    原文:计算机视觉识别简史:从 AlexNet.ResNet 到 Mask RCNN 总是找不到原文,标记一下.        一切从这里开始:现代物体识别随着ConvNets的发展而发展,这一切始于2 ...

  3. 原型&&原型链一语道破梦中人

    一直对原型和原型链模模糊糊,今天看到一句话,通过这句话再结合我目前对原型和原型链的理解算是让我对原型和原型链有一个更清醒的认识;并且记忆更加深刻; 任何一个对象都有一个隐式原型:__proto__属性 ...

  4. 几校联考——day1题解

    T1 约数的个数(好像不可提交) 如果一个整数a能够整除整数b,那么a叫做b的约数.现在有N(1 <= N <= 100,000)个整数,对于其中的每一个数,请找出它在其余N - 1个整数 ...

  5. 标准C 语言总结

    ***************C语言****************** --day01-- Linux是一个和Windows类似的操作系统 通常通过终端软件使用Linux操作系统 终端软件里只能使用 ...

  6. idea和eclipse互相导入方法

    1.eclipse maven项目导入idea 只需要在pom.xml文件中加入如下图 为了加载项目里的一些配置文件(例如.xml和.properties文件) 2.idea maven 项目导入ec ...

  7. Cent os常见操作命令

    1.查看防火墙状态:firewall-cmd –-state 2.关闭防火墙:systemctl stop firewalld.service 3.禁止防火墙开机启动:systemctl disabl ...

  8. bupt summer training for 16 #4 ——数论

    https://vjudge.net/contest/173277#overview A.平方差公式后变为 n = (x + y)(x - y) 令 t = x - y ,变成 n = (t + 2x ...

  9. poj 1273最大流dinic算法模板

    #include<stdio.h> #include<string.h> #define N 300 #define inf 0x7fffffff #include<qu ...

  10. Spring Boot 内嵌容器 Tomcat / Undertow / Jetty 优雅停机实现

    Spring Boot 内嵌容器 Tomcat / Undertow / Jetty 优雅停机实现 Anoyi 精讲JAVA 精讲JAVA 微信号 toooooooozi 功能介绍 讲解java深层次 ...