题意: 在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. bzoj 2434 fail tree+dfs序

    首先比较明显的是我们可以将字符串组建立ac自动机,那么对于询问s1字符串在s2字符串中出现的次数,就是在以s1结尾为根的fail tree中,子树有多少个节点是s2的节点,这样我们处理fail tre ...

  2. Android日历开发之右上角标注红点事件

    1.效果如下所示: 2.方法:      前提:已经知道如何在右上角画圆点的情况下.      这是一个任务显示器,每个任务都有一个时间,比如2014.01.12.      如果要标注2016.08 ...

  3. 通用套接字选项和TCP套接字选项

    1. 套接字选项函数原型: #include <sys/socket.h> int getsockopt(int sockfd, int level, int optname, void ...

  4. "Flags mismatch irq" register interrupt handler error

    Question : When you see the log "Flags mismatch irq ............", maybe you use the same ...

  5. monkey测试===easyMonkey测试【推荐】

    easymonkey测试: easymonkey是基于monkey测试的一个二次开发工具.(关于monkey测试参见之前blog) easymonkey的特点就是方便,解决了很多参数命令上设置的麻烦, ...

  6. MYSQL表中设置字段类型为TIMESTAMP时的注意事项

    在MYSQL中,TIMESTAMP类型是用来表示日期的,但是和DATETIME不同,不同点就不再这里说明了. 当我们在使用TIMESTAMP类型设置表中的字段时,我们应该要注意一点,首先我们在表中新增 ...

  7. sharding-JDBC 实现读写分离

    需求 一主两从,做读写分离. 多个从库之间实现负载均衡. 可手动强制部分读请求到主库上.(因为主从同步有延迟,对实时性要求高的系统,可以将部分读请求也走主库) 本次不讨论 MySQL如何配置主从同步相 ...

  8. poj 1088(记忆化搜索)

    滑雪 Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 88560   Accepted: 33212 Description ...

  9. Nginx错误:nginx: [error] OpenEvent("Global\ngx_reload_6252") failed (2: The system cannot find the file specified)

    执行nginx -s reload命令: nginx: [error] OpenEvent("Global\ngx_reload_6252") failed (2: The sys ...

  10. SpringMVC组件配置

    web.xml . springmvc-servlet.xml 配置SpringMVC四大组件. web.xml 配置前端控制器:前端控制器就是个servlet <!-- 配置前端控制器 --& ...