题意: 在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. [IOS]vmxsmc.exe已停止工作 VMware11 Unlocker for Mac OSX无法使用的解决办法.

    今天我帮同事安装VMware workstation12后发现之前的unlocker已经无法进行解锁了(就是VMware新建虚拟机无App Mac选项) 使用unlocker会出现vmsxmc.exe ...

  2. Centos 7 安装jdk1.7

    在linux中安装jdk是很平凡的事情了,刚学习linux给自己留下一笔记.刚安装centos其中可以会附带jdk,但是这并不影响,只要下载自己的jdk然后替换相对应的环境变量即可. 1.下载相对应的 ...

  3. ie8下trim失效

    1.ie8下使用trim失效 trim可以除去字符串两侧的空白字符,但ie8并不支持 2.解决方案 String.prototype.trim = function () { return this ...

  4. Python3 xml模块的增删改查

    xml数据示例 ? 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 <data>     < ...

  5. 内存分配器memblock【转】

    转自:http://blog.csdn.net/kickxxx/article/details/54710243 版权声明:本文为博主原创文章,未经博主允许不得转载. 目录(?)[-] 背景 Data ...

  6. 【bzoj4448】SCOI2015 情报传递

    树剖,可以相当于一个染色问题,以及询问先前节点的染色个数. 把第二种操作离线掉,然后用线段树模拟即可. #include<bits/stdc++.h> #define N 800010 # ...

  7. 【Educational Codeforces Round 22】

    又打了一场EDU,感觉这场比23难多了啊…… 艹还是我太弱了. A. 随便贪心一下. #include<bits/stdc++.h> using namespace std; ,ans=- ...

  8. VI编辑,backspace无法删除解决方法

    系统ubuntu 1,sudo apt-get install vim  安装vim 2, sudo vi  /etc/vim/vimrc.tiny 修改 set compatible为set noc ...

  9. RadioButton 带下划线切换的案例

    xml <?xml version="1.0" encoding="utf-8"?> <RelativeLayout android:id=& ...

  10. JQuery判断一个元素下面是否有内容或者有某个标签

    网站开发时,我们时常需要把没有内容的标签隐藏或者去掉.在用JQ有两种好的解决办法: 一.判断文本是否为空 var jqObj = $(this);if(jqObj.text().trim()){ // ...