tarjan代码
还有五天就是NOIP2018了……本蒟蒻还要复习期中考试,因此实在没有时间写博客了(各种找借口)。这里就放一下代码
//Tarjan缩点
//题目描述:给一个有向图。每个点有一个权值,求权值和最大的路径的权值和
#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<algorithm>
#include<cmath>
#include<stack>
#include<queue>
#define MAXN 10005
#define MAXM 100005
using namespace std; inline int read()
{
int f=,x=;
char ch=getchar();
while(ch<'' || ch>'') {if(ch=='-') f=-; ch=getchar();}
while(ch>='' && ch<='') {x=x*+ch-''; ch=getchar();}
return x*f;
} int n,m;
int cnt,num,tot,ans;
int u[MAXM],v[MAXM],head[MAXN],nxt[MAXM];//邻接表部分
int dfn[MAXN],low[MAXN];//tarjan部分
bool book[MAXN];
stack <int> s;
int p[MAXN],sd[MAXN],in_d[MAXN],dis[MAXN];//缩点+拓扑部分
queue <int> q; void add(int x,int y)
{
u[++cnt]=x;//存起点以供后续重新建图使用
v[cnt]=y;
nxt[cnt]=head[x];
head[x]=cnt;
} void tarjan(int x)
{
dfn[x]=low[x]=++num;
book[x]=;
s.push(x);
for(int i=head[x];i;i=nxt[i])//标准tarjan
{
int t=v[i];
if(!dfn[t])
{
tarjan(t);
low[x]=min(low[x],low[t]);
}
else if(book[t])
low[x]=min(low[x],dfn[t]);
}
if(low[x]==dfn[x])
{
tot++;
while(s.top()!=x)
{
int y=s.top();
book[y]=;
p[x]+=p[y];//缩点的权值
sd[y]=x;//缩点标记
s.pop();
}
book[x]=;
sd[x]=x;
s.pop();
}
} int main()
{
int i;
int x,y;
n=read(); m=read();
for(i=;i<=n;i++) p[i]=read();
for(i=;i<=m;i++)
{
x=read();
y=read();
add(x,y);//有向图
}
for(i=;i<=n;i++)
if(!dfn[i])
tarjan(i); memset(head,,sizeof(head));
memset(nxt,,sizeof(nxt));
for(i=;i<=m;i++)//将缩后的点重新建图
{
x=sd[u[i]],y=sd[v[i]];
if(x!=y)
{
add(x,y);
in_d[y]++;//每个点的入度(拓扑使用)
}
}
for(i=;i<=n;i++)//利用拓扑搞dp,求最大权值路径
{
if(sd[i]==i && !in_d[i])
{
q.push(i);
dis[i]=p[i];//记得要把自己开始时的权值设成点权
}
}
while(!q.empty())
{
int x=q.front(); q.pop();
for(i=head[x];i;i=nxt[i])
{
int t=v[i];
dis[t]=max(dis[t],dis[x]+p[t]);
in_d[t]--;
if(!in_d[t]) q.push(t);//入度等于零,根据拓扑,入队
}
}
for(i=;i<=n;i++)
ans=max(ans,dis[i]);
printf("%d",ans);
return ;
}
//Tarjan求割点
#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<algorithm>
#include<cmath>
#define MAXN 20005
#define MAXM 200005
using namespace std; inline int read()
{
int f=,x=;
char ch=getchar();
while(ch<'' || ch>'') {if(ch=='-') f=-; ch=getchar();}
while(ch>='' && ch<='') {x=x*+ch-''; ch=getchar();}
return x*f;
} int n,m;
int cnt,num,ans;
int v[MAXM],head[MAXN],nxt[MAXM];
int dfn[MAXN],low[MAXN];
bool cut[MAXN];
int i,j; void add(int a,int b)
{
v[++cnt]=b;
nxt[cnt]=head[a];
head[a]=cnt;
} void tarjan(int x,int fa)
{
int Child=;
dfn[x]=low[x]=++num;
for(int i=head[x];i;i=nxt[i])
{
int nx=v[i];
if(!dfn[nx])
{
tarjan(nx,fa);
low[x]=min(low[x],low[nx]);
Child++;
if(x!=fa && dfn[x]<=low[nx])
cut[x]=;
}
else low[x]=min(low[x],dfn[nx]); //这行不要写错
}
if(x==fa && Child>=)
cut[x]=;
} int main()
{
int i;
int a,b;
n=read(); m=read();
for(i=;i<=m;i++)
{
a=read();
b=read();
add(a,b);
add(b,a);
}
for(i=;i<=n;i++)
if(!dfn[i])
tarjan(i,i);
for(i=;i<=n;i++)
if(cut[i]) ans++;
printf("%d\n",ans);
for(i=;i<=n;i++)
if(cut[i])
printf("%d ",i);
return ;
}
~NOIP2018 加油~
tarjan代码的更多相关文章
- tarjan讲解(用codevs1332(tarjan的裸题)讲解)
主要借助这道比较裸的题来讲一下tarjan这种算法 tarjan是一种求解有向图强连通分量的线性时间的算法.(用dfs来实现) 如果两个顶点可以相互通达,则称两个顶点强连通.如果有向图G的每两个顶点都 ...
- POJ 1144 Network(Tarjan求割点)
Network Time Limit: 1000MS Memory Limit: 10000K Total Submissions: 12707 Accepted: 5835 Descript ...
- 强连通分量(tarjan求强连通分量)
双DFS方法就是正dfs扫一遍,然后将边反向dfs扫一遍.<挑战程序设计>上有说明. 双dfs代码: #include <iostream> #include <cstd ...
- [NOIP2009][LuoguP1073] 最优贸易 - Tarjan,拓扑+DP
Description&Data 题面:https://www.luogu.org/problemnew/show/P1073 Solution Tarjan对联通块缩点,在DAG上按照拓扑序 ...
- 利用Tarjan算法解决(LCA)二叉搜索树的最近公共祖先问题——数据结构
相关知识:(来自百度百科) LCA(Least Common Ancestors) 即最近公共祖先,是指在有根树中,找出某两个结点u和v最近的公共祖先. 例如: 1和7的最近公共祖先为5: 1和5的 ...
- Tarjan模板题——牛的舞会
题目描述 约翰的N (2 <= N <= 10,000)只奶牛非常兴奋,因为这是舞会之夜!她们穿上礼服和新鞋子,别 上鲜花,她们要表演圆舞. 只有奶牛才能表演这种圆舞.圆舞需要一些绳索和一 ...
- POJ 1236 Network of Schools(tarjan)题解
题意:一个有向图.第一问:最少给几个点信息能让所有点都收到信息.第二问:最少加几个边能实现在任意点放信息就能传遍所有点 思路:把所有强连通分量缩成一点,然后判断各个点的入度和出度 tarjan算法:问 ...
- HDU 4685 Prince and Princess 二分图匹配+tarjan
Prince and Princess 题目连接: http://acm.hdu.edu.cn/showproblem.php?pid=4685 Description There are n pri ...
- POJ 3648 Wedding(2-SAT的模型运用+DFS | Tarjan)
Wedding Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 10427 Accepted: 3170 Specia ...
随机推荐
- 超简单的okHttpUtils封装(下)
版权声明:转载请注明出处:http://blog.csdn.net/piaomiao8179 https://blog.csdn.net/piaomiao8179/article/details/ ...
- hive SQL 静态分区和 动态分区
Hive 分区介绍: hive中简单介绍分区表(partition table),含动态分区(dynamic partition)与静态分区(static partition) hive中创建分区表没 ...
- 【转载】Linux 命令行快捷键 - 移动光标
Linux 命令行快捷键 - 移动光标 涉及在linux命令行下进行快速移动光标.命令编辑.编辑后执行历史命令.Bang(!)命令.控制命令等.让basher更有效率. 常用 ctrl+左右键:在单词 ...
- 隐马尔可夫模型:HMM
隐马尔可夫模型求解三大问题实例剖析 HMM 模型如图所示: 一.隐马尔可夫模型定义 隐马尔可夫模型由初始概率分布.状态转移概率分布以及观测概率分布确定. 设 Q(图中的q)是所有可能的状态的集合,V( ...
- Linux常用指令笔记
目标:统计当前目录下java文件的个数 指令:`ls -R ./ | grep .java$ | wc -l` 原理:`ls -R ./`列出当前文件夹下的所有FILE,包括目录以及文件;`grep ...
- 一对一voip,直播连麦,在线会议,兼容webrtc,IM音视频
功能 IM消息系统 一对一 高清音视频实时通信,可无缝切换P2P传输,节省服务器带宽 一对多互动直播 多对多在线会议 手机实时录屏传输 高度定制化 网络检测,动态码率与动态帧率,抗网络抖动,微信级效果 ...
- [sqoop] sqoop 小试牛刀
sqoop 1.4.6 小试牛刀 sqoop import 参数 1. mysql导入 到hdfs中 ./sqoop import --connect jdbc:mysql://mysql:3306 ...
- xib view frame 大小调整
1.IOS - xib(Interface Builder,view) - can't change view size(view不能改变大小问题) 很多时候,我们自定义tableview.colle ...
- 64位 windows10,安装配置MYSQL8.0.13
MySQL的安装配置过程,一查网上一大堆,但是每个人在安装配置的过程中都会碰到一些问题,因为安装的版本不一样,有些命令可能就不适用了.所以安装之前一定先确认好你的版本号. 下面开始安装MYSQL8.0 ...
- iOS 调试大法
本文转载至 http://www.jianshu.com/p/d19e19a91071 0.笨办法 看变量.对象?NSLog+重新编译运行:改某对象?改源码+重新编译运行:隔离某个方法?在方法中写 r ...