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 ...
随机推荐
- Visual Studio 2015 msvsmon.exe crashed when c++ debugging with x64
Completely uninstalling Astrill fixed the issue but this solution is not what I want. Astrill suppor ...
- python serial 模块使用
python3 开始, python 加入了 serial 操作串口的模块 模块的引用 import serial 串口的申请 serial_com1 = serial.Serial("/d ...
- 开始学习Functional Programming
打算先学F#, 再学Scala. 第一个F#程序 open System [<EntryPoint>] let main argv = let a = "Hello, World ...
- MyBatis 配置多数据源
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.sp ...
- JavaScript学习历程03
一闪一闪亮晶晶 <script type="text/javascript"> var nn = Number(prompt('请输入一个1-9的正整数!')); va ...
- 【hbase】Unable to read additional data from client sessionid 0x15c92bd1fca0003, likely client has closed socket
启动hbase ,验证出错 Master is initializing 查看zk日志,发现Unable to read additional data from client sessionid 0 ...
- iOS 调试大法
本文转载至 http://www.jianshu.com/p/d19e19a91071 0.笨办法 看变量.对象?NSLog+重新编译运行:改某对象?改源码+重新编译运行:隔离某个方法?在方法中写 r ...
- 转载:【Scala】使用Option、Some、None,避免使用null
转载自Jason DingGitCafe博客主页(http://jasonding1354.gitcafe.io/)Github博客主页(http://jasonding1354.github.io/ ...
- C++学习 —— 重新认识C++
我大概是从读研究生入学那天开始,想要学好C++的,学习C++几乎也成了我每个学期的计划之一.为什么会每个学期都想要学好C++呢?因为每次学习都失败了啊... 本月,我开始再Coursera上学习Het ...
- pycharm 2018.1 激活
pycharm 2018.1 License server 填入 https://jetlicense.nss.im/ 激活没有问题 测试时间 2018.4.18