【强连通分量缩点】【拓扑排序】【dp预处理】CDOJ1640 花自飘零水自流,一种相思,两处闲愁。
题意: 在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 花自飘零水自流,一种相思,两处闲愁。的更多相关文章
- POJ2762 Going from u to v or from v to u?(判定单连通图:强连通分量+缩点+拓扑排序)
这道题要判断一张有向图是否是单连通图,即图中是否任意两点u和v都存在u到v或v到u的路径. 方法是,找出图中所有强连通分量,强连通分量上的点肯定也是满足单连通性的,然后对强连通分量进行缩点,缩点后就变 ...
- 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. ...
- 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 ...
- 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 ...
- FFF at Valentine(强连通分量缩点+拓扑排序)
FFF at Valentine Time Limit: 6000/3000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others) ...
- UVA 11324 The Largest Clique(强连通分量+缩点DAG的DP)
题意:给定一个有向图,求出一个最大的结点集,这个节点集中的随意两个点之间至少一个能到达还有一个点. 思路:假设一个点在这个节点集中,那么它所在的强连通分量中的点一定所有在这个节点集中,反之亦然, 求出 ...
- [luogu2272 ZJOI2007] 最大半连通子图 (tarjan缩点 拓扑排序 dp)
传送门 题目描述 一个有向图G=(V,E)称为半连通的(Semi-Connected),如果满足:?u,v∈V,满足u→v或v→u,即对于图中任意两点u,v,存在一条u到v的有向路径或者从v到u的有向 ...
- [ZJOI2007]最大半连通子图 (Tarjan缩点,拓扑排序,DP)
题目链接 Solution 大概是个裸题. 可以考虑到,如果原图是一个有向无环图,那么其最大半联通子图就是最长的一条路. 于是直接 \(Tarjan\) 缩完点之后跑拓扑序 DP就好了. 同时由于是拓 ...
- BZOJ_3887_[Usaco2015 Jan]Grass Cownoisseur_强连通分量+拓扑排序+DP
BZOJ_3887_[Usaco2015 Jan]Grass Cownoisseur_强连通分量+拓扑排序+DP Description In an effort to better manage t ...
随机推荐
- css优先级机制
所谓CSS优先级,即是指CSS样式在浏览器中被解析的先后顺序. 1.important >(内联样式)Inline style >(内部样式)Internal style sheet ...
- 关于ssh三大框架整合的碎碎念
三大框架整合,无非就是一个导jar包,修改配置文件的过程.完了就没事了. 还是有很多细节性的问题 比如在spring中写applicationContext.xml文件时不提示: 解决方法如下: 如果 ...
- quartz的简介
1. 介绍 Quartz是OpenSymphony开源组织在Job scheduling领域又一个开源的任务调度框架,是完全由java开发的一个开源的任务日程管理系统,“任务进度管理器”就是一个在预 ...
- redis线程安全性
总体来说快速的原因如下: 1)绝大部分请求是纯粹的内存操作(非常快速) 2)采用单线程,避免了不必要的上下文切换和竞争条件 3)非阻塞IO 内部实现采用epoll,采用了epoll+自己实现的简单的事 ...
- 辨别苹果数据线真伪 苹果计算器 Dashboard 知识
辨别苹果数据线真伪 苹果计算器 Dashboard 知识 苹果数据线真伪的最简单的辨别: 线质柔软 用数据线连接适配器(苹果自带的适配器)充电 连接手机 如果该手机数据线是假的, 在手机上会提示”该 ...
- centos7.4关闭防火前
systemctl stop firewalld.service #停止firewallsystemctl disable firewalld.service #禁止firewall开机启动firew ...
- linux命令--head
head 与 tail 就像它的名字一样的浅显易懂,它是用来显示开头或结尾某个数量的文字区块,head 用来显示档案的开头至标准输出中,而 tail 想当然尔就是看档案的结尾. 具体使用参考链接: h ...
- Java显式锁学习总结之一:概论
我们都知道在java中,当多个线程需要并发访问共享资源时需要使用同步,我们经常使用的同步方式就是synchronized关键字,事实上,在jdk1.5之前,只有synchronized一种同步方式.而 ...
- Flash中的注册点和中心点
用一句话概括注册点和中心点的作用,那就是:注册点用来定位,中心点用来变形 当然,这句话不是非常准确,只是暂时先这么理解,下面会详细讲解. 认识注册点 每个元件都有一个注册点.在元件编辑窗口.或在舞台中 ...
- canvas 进入游戏点击时苹果手机为什么会闪
canvas 进入游戏点击时苹果手机为什么会闪 ?? 大神门 谁有解决办法???