题意: 在n个点m条边的有向图上,从1出发的回路最多经过多少个不同的点 可以在一条边上逆行一次

题解: 在同一个强连通分量中,显然可以经过当中的每一个点 因此先将强连通分量缩点,点权为强连通分量的点数

如果不逆行,那么答案就是1所在的强连通分量的点数 如果逆行了,那么逆行的边必然在缩点后的拓扑图上

假设逆行的边为u->v,那么该回路可分为1到v和u到1两部分 经过的最多点数即1到v与u到1路径上的最大点权和减去1的点权 (这里的点指的都是缩点后的点)

例子中在边4->3上逆行就能从1出发经过所有点回到1

那么预处理拓扑图上1到每个点的最大点权和及每个点到1的最大点权和(将边倒过来搞一次就行) 枚举逆行的边即可得到答案。

#include<cstdio>
#include<cstring>
#include<queue>
#include<algorithm>
#include<vector>
using namespace std;
typedef long long ll;
vector<int>G[100010],rG[100010],vs;
bool used[100010];
int cmp[100010],x[100010],y[100010],a[100010],f[100010],g[100010],ru[100010],ru2[100010];
int n,m,K;
void dfs(int U){
used[U]=1;
for(int i=0;i<G[U].size();++i){
if(!used[G[U][i]]){
dfs(G[U][i]);
}
}
vs.push_back(U);
}
void rdfs(int U){
used[U]=1;
cmp[U]=K;
for(int i=0;i<rG[U].size();++i){
if(!used[rG[U][i]]){
rdfs(rG[U][i]);
}
}
}
int main(){
scanf("%d%d",&n,&m);
for(int i=1;i<=m;++i){
scanf("%d%d",&x[i],&y[i]);
G[x[i]].push_back(y[i]);
rG[y[i]].push_back(x[i]);
}
for(int i=1;i<=n;++i){
if(!used[i]){
dfs(i);
}
}
memset(used,0,sizeof(used));
for(int i=vs.size()-1;i>=0;--i){
if(!used[vs[i]]){
++K;
rdfs(vs[i]);
}
}
for(int i=1;i<=n;++i){
G[i].clear();
rG[i].clear();
}
for(int i=1;i<=m;++i){
if(cmp[x[i]]!=cmp[y[i]]){
G[cmp[x[i]]].push_back(cmp[y[i]]);
++ru[cmp[y[i]]];
rG[cmp[y[i]]].push_back(cmp[x[i]]);
++ru2[cmp[x[i]]];
}
}
for(int i=1;i<=n;++i){
++a[cmp[i]];
}
queue<int>q;
for(int i=1;i<=K;++i){
if(!ru[i]){
q.push(i);
}
}
memset(f,0xaf,sizeof(f));
f[cmp[1]]=a[cmp[1]];
while(!q.empty()){
int U=q.front(); q.pop();
for(int i=0;i<G[U].size();++i){
f[G[U][i]]=max(f[G[U][i]],f[U]+a[G[U][i]]);
--ru[G[U][i]];
if(!ru[G[U][i]]){
q.push(G[U][i]);
}
}
} for(int i=1;i<=K;++i){
if(!ru2[i]){
q.push(i);
}
}
memset(g,0xaf,sizeof(g));
g[cmp[1]]=a[cmp[1]];
while(!q.empty()){
int U=q.front(); q.pop();
for(int i=0;i<rG[U].size();++i){
g[rG[U][i]]=max(g[rG[U][i]],g[U]+a[rG[U][i]]);
--ru2[rG[U][i]];
if(!ru2[rG[U][i]]){
q.push(rG[U][i]);
}
}
} int ans=a[cmp[1]];
for(int i=1;i<=m;++i){
if(cmp[x[i]]!=cmp[y[i]]){
ans=(int)max((ll)ans,(ll)f[cmp[y[i]]]+(ll)g[cmp[x[i]]]-(ll)a[cmp[1]]);
}
}
printf("%d\n",ans);
return 0;
}

【强连通分量缩点】【拓扑排序】【dp预处理】CDOJ1640 花自飘零水自流,一种相思,两处闲愁。的更多相关文章

  1. POJ2762 Going from u to v or from v to u?(判定单连通图:强连通分量+缩点+拓扑排序)

    这道题要判断一张有向图是否是单连通图,即图中是否任意两点u和v都存在u到v或v到u的路径. 方法是,找出图中所有强连通分量,强连通分量上的点肯定也是满足单连通性的,然后对强连通分量进行缩点,缩点后就变 ...

  2. POJ 2762 Going from u to v or from v to u? (强连通分量缩点+拓扑排序)

    题目链接:http://poj.org/problem?id=2762 题意是 有t组样例,n个点m条有向边,取任意两个点u和v,问u能不能到v 或者v能不能到u,要是可以就输出Yes,否则输出No. ...

  3. POJ2762 Going from u to v or from v to u? 强连通分量缩点+拓扑排序

    题目链接:https://vjudge.net/contest/295959#problem/I 或者 http://poj.org/problem?id=2762 题意:输入多组样例,输入n个点和m ...

  4. poj 2762 Going from u to v or from v to u?【强连通分量缩点+拓扑排序】

    Going from u to v or from v to u? Time Limit: 2000MS   Memory Limit: 65536K Total Submissions: 15812 ...

  5. FFF at Valentine(强连通分量缩点+拓扑排序)

    FFF at Valentine Time Limit: 6000/3000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others) ...

  6. UVA 11324 The Largest Clique(强连通分量+缩点DAG的DP)

    题意:给定一个有向图,求出一个最大的结点集,这个节点集中的随意两个点之间至少一个能到达还有一个点. 思路:假设一个点在这个节点集中,那么它所在的强连通分量中的点一定所有在这个节点集中,反之亦然, 求出 ...

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

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

  8. [ZJOI2007]最大半连通子图 (Tarjan缩点,拓扑排序,DP)

    题目链接 Solution 大概是个裸题. 可以考虑到,如果原图是一个有向无环图,那么其最大半联通子图就是最长的一条路. 于是直接 \(Tarjan\) 缩完点之后跑拓扑序 DP就好了. 同时由于是拓 ...

  9. BZOJ_3887_[Usaco2015 Jan]Grass Cownoisseur_强连通分量+拓扑排序+DP

    BZOJ_3887_[Usaco2015 Jan]Grass Cownoisseur_强连通分量+拓扑排序+DP Description In an effort to better manage t ...

随机推荐

  1. cnn 卷积神经网络 人脸识别

    卷积网络博大精深,不同的网络模型,跑出来的结果是不一样,在不知道使用什么网络的情况下跑自己的数据集时,我建议最好去参考基于cnn的手写数字识别网络构建,在其基础上进行改进,对于一般测试数据集有很大的帮 ...

  2. Python面向对象学习2(面向对象的语法和特性,待更新)

    上一个内容我们介绍了面向对象和面向对象场景现在我们来学习下语法和特性 1,面向对象基本语法: # -*- coding:utf-8 -*- # Author: Colin Yao class Dog( ...

  3. 【目录】Python自动化运维

    目录:Python自动化运维笔记 Python自动化运维 - day2 - 数据类型 Python自动化运维 - day3 - 函数part1 Python自动化运维 - day4 - 函数Part2 ...

  4. hadoop入门学习

    hadoop入门学习:http://edu.csdn.net/course/detail/1397hadoop hadoop2视频:http://pan.baidu.com/s/1o6uy7Q6HDF ...

  5. linux 设备树【转】

    转自:http://blog.csdn.net/chenqianleo/article/details/77779439 [-] linux 设备树 为什么要使用设备树Device Tree 设备树的 ...

  6. python基础===Python 迭代器模块 itertools 简介

    本文转自:http://python.jobbole.com/85321/ Python提供了一个非常棒的模块用于创建自定义的迭代器,这个模块就是 itertools.itertools 提供的工具相 ...

  7. centos_7.1.1503_src_5

    http://vault.centos.org/7.1.1503/os/Source/SPackages/ minicom-2.6.2-5.el7.src.rpm 05-Jul-2014 13:50 ...

  8. Linux(Unix)密码策略问题导致root密码不能修改

    Linux(Unix)密码策略问题导致root密码不能修改 发布时间:  2016-01-19 浏览次数:  1034 下载次数:  5 用户修改了密码配置文件,导致root账户修改密码时报如下错误: ...

  9. FreeRADIUS + MySQL 安装配置笔记

    FreeRADIUS + MySQL 安装配置笔记 https://www.2cto.com/net/201110/106597.html

  10. python windows下安装celery调度任务时出错

    由于celery 4.0不支持windows系统.所以用命令pip install Celery安装的celery是最新版4.0的不能在windows下运行. 在windows命令窗口运行: cele ...