题目: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. 在mac上快捷找到nodejs的安装路径

    打开控制台输入 which node ,得到的输出结果就是node安装路径

  2. JS——scroll

    scrollWidth:父div宽度小于子div宽度,父div scrollWidth宽度为子div的宽度,大于则为本身的宽度width+padding scrollHeight:父div高度小于子d ...

  3. Java_Web三大框架之Hibernate+HQL语言基础

    12.1 HQL语言基础Hibernate查询语言为HQL(Hibernate Query Language),可以直接使用实体类名及属性.HQL语法类似于SQL,有SQL的关键词如select.fr ...

  4. 查看APK包名签名等信息

    有些游戏第三方比如分享需要配置游戏包名和签名,不同渠道包名签名又不同,所以时常需要查看不同apk包等签名信息,之前是使用等微博开放平台的手机客户端查看apk签名,前提是知道包名,网上找了下查看签名和包 ...

  5. How an SSL connection is established

    An SSL connection between a client and server is set up by a handshake, the goals of which are: To s ...

  6. 34.分组聚合操作—bucket

    主要知识点: 学习聚合知识     一.准备数据     1.家电卖场案例背景建立index 以一个家电卖场中的电视销售数据为背景,来对各种品牌,各种颜色的电视的销量和销售额,进行各种各样角度的分析 ...

  7. Windows Phone开发(18):变形金刚第九季

    变换不是一个好理解的概念,不是吓你,它涉及很多有关代数,几何,以及线性代数的知识.怎么?被我的话吓怕了?不用怕,尽管我们未必能够理解这些概念,只要我们知道怎么使用它们就是了.其实,变换就是平面上一种坐 ...

  8. BZOJ 1232 USACO 2008 Nov. 安慰奶牛Cheer

    [题解] 对于每一条边,我们通过它需要花费的代价是边权的两倍加上这条边两个端点的点权. 我们把每条边的边权设为上述的值,然后跑一边最小生成树,再把答案加上最小的点权就好了. #include<c ...

  9. Beetl学习总结(4)——Web集成

    4.1. Web提供的全局变量 Web集成模块向模板提供web标准的变量,做如下说明 request 中的所有attribute.在模板中可以直接通过attribute name 来引用,如在cont ...

  10. Java POI Excel 导入导出

    这个东西很容易懂,不是特别难,难就难在一些复杂的计算和Excel格式的调整上. 近期写了一个小列子,放上来便于以后使用. POI.jar下载地址:http://mirror.bit.edu.cn/ap ...