思路

tarjan的题目

注意是要选出一个点集而不是边集

第一问就是缩点之后最长链,第二问就是有多少个最长链,注意缩点后连边要去重(不然一个链的方案可能会被统计多次)

代码

#include <cstdio>
#include <algorithm>
#include <cstring>
#include <stack>
#include <set>
using namespace std;
int scc_cnt,sccno[100100],sccnum[100100],low[100100],dfn[100100],vis[100100],vis2[100100],dp1[100100],dfs_clock,n,m,MOD;
pair<int,int> dp2[100100];
struct Graph{
int u[1001000],v[1001000],fir[1001000],nxt[1001000],cnt=0;
void addedge(int ui,int vi){
++cnt;
u[cnt]=ui;
v[cnt]=vi;
nxt[cnt]=fir[ui];
fir[ui]=cnt;
}
}G1,G2;
stack<int> S;
set<pair<int,int> > S2;
void tarjan(int u){
low[u]=dfn[u]=++dfs_clock;
S.push(u);
vis[u]=true;
for(int i=G1.fir[u];i;i=G1.nxt[i]){
if(!dfn[G1.v[i]]){
tarjan(G1.v[i]);
low[u]=min(low[u],low[G1.v[i]]);
}
else if(vis[G1.v[i]])
low[u]=min(low[u],low[G1.v[i]]);
}
if(dfn[u]==low[u]){
scc_cnt++;
while(1){
int x=S.top();
S.pop();
vis[x]=false;
sccno[x]=scc_cnt;
if(x==u)
break;
}
}
}
void sd(void){
for(int i=1;i<=n;i++)
if(!dfn[i])
tarjan(i);
for(int i=1;i<=n;i++){
sccnum[sccno[i]]++;
for(int j=G1.fir[i];j;j=G1.nxt[j]){
int u=sccno[i],v=sccno[G1.v[j]];
if(u>v)
swap(u,v);
if(S2.count(make_pair(u,v)))
continue;
S2.insert(make_pair(u,v));
if(sccno[i]!=sccno[G1.v[j]])
G2.addedge(sccno[i],sccno[G1.v[j]]);
}
}
}
int dfs1(int x){
if(vis[x])
return dp1[x];
vis[x]=true;
for(int i=G2.fir[x];i;i=G2.nxt[i]){
dp1[x]=max(dfs1(G2.v[i]),dp1[x]);
}
dp1[x]+=sccnum[x];
return dp1[x];
}
pair<int,int> dfs2(int x){
if(vis2[x])
return dp2[x];
vis2[x]=true;
dp2[x]=make_pair(0,1);
for(int i=G2.fir[x];i;i=G2.nxt[i]){
pair<int,int> t=dfs2(G2.v[i]);
if(t.first>dp2[x].first){
dp2[x]=t;
}
else if(t.first==dp2[x].first){
dp2[x].second=(dp2[x].second+t.second)%MOD;
}
}
dp2[x].first+=sccnum[x];
return dp2[x];
}
int main(){
scanf("%d %d %d",&n,&m,&MOD);
for(int i=1;i<=m;i++){
int a,b;
scanf("%d %d",&a,&b);
G1.addedge(a,b);
}
sd();
int ans=0,ans2=0;
for(int i=1;i<=scc_cnt;i++)
ans=max(ans,dfs1(i));
for(int i=1;i<=scc_cnt;i++){
pair<int,int> t=dfs2(i);
if(t.first==ans)
ans2=(ans2+t.second)%MOD;
}
printf("%d\n%d\n",ans,ans2);
return 0;
}

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

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

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

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

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

  3. luogu P2272 [ZJOI2007]最大半连通子图

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

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

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

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

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

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

    题目大意 题目是图片形式的,就简要说下题意算了 一个有向图 G=(V, E) 称为半连通的(Semi-Connected),如果满足图中任意两点 u v,存在一条从 u 到 v 的路径或者从 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: [ZJOI2007]最大半连通子图( tarjan + dp )

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

随机推荐

  1. Python - 5.Exception Handling

    From:http://interactivepython.org/courselib/static/pythonds/Introduction/ExceptionHandling.html Exce ...

  2. mysql安装使用

    linux系统 mysql-5.7.14-linux.zip部署包支持在CentOS 6.x/7.x 服务器硬盘大小要求 a) /data/mysql_data  如果存在该独立分区,要求该分区 &g ...

  3. 微信小程序制作家庭记账本之六

    第六天,自己根据样本代码做的记账本可实现添加账目,删除账目和消费总和,实机可以测试,但是没有域名,别人无法访问.

  4. Codeforce 507B - Amr and Pins

    Amr loves Geometry. One day he came up with a very interesting problem. Amr has a circle of radius r ...

  5. Oracle之数据库的增删改查和格式的修改

    Oracle修改数据 *update语句 格式: update table_name set column1=value1,…[where conditions] 例子: update userinf ...

  6. JDBC和servlet设计思路、DAO模式思路、MVC思路粗略总结

    #JDBC和Servlet联合起来使用的项目思路: 说明:建库,最好一开始设置utf8字符集 step1: 在数据库中建表 如   create table t_user{ ...... } step ...

  7. The logback manual #01# Introduction

    依赖包如下pom.xml: <?xml version="1.0" encoding="UTF-8"?> <project xmlns=&qu ...

  8. 搭建一个简单的svn服务器(旧)

    cenos 6.5,svnserver 1.6.11 默认可能已经安装,没有的话就: yum install svn -ysvnserver --version 创建一个svn仓库: svnadmin ...

  9. oracle 18c的版本号规则

    18C之后的版本标识 从2017年7月开始,Oracle改变了以往的数据库软件发布流程,采用年度Release和季度更新的策略. Yearly Release 将之前的N年一发布更改为每年一发布.每年 ...

  10. py4CV例子1猫狗大战和Knn算法

    1.什么是猫狗大战: 数据集来源于Kaggle(一个为开发商和数据科学家提供举办机器学习竞赛.托管数据库.编写和分享代码的平台),原数据集有12500只猫和12500只狗,分为训练.测试两个部分. 2 ...