透彻tarjan
tarjan 求强连通分量:
#include<cstdio>
#include<iostream>
#include<cstdlib>
#define N 1000000
#include<vector>
vector <int> scc;
int sta[N],dfn[N],low[N],in[N],tar[N],tot,tp,cnt;
void tarjan(int x)
{
dfn[x]=low[x]=++tot;
sta[++tp]=x;
in[x]=1;
for(int i=head[x];i;i=e[i].nxt)
{
if(!dfn[e[i].to])
{
tarjan(e[i].to);
low[x]=min(low[x],low[e[i].to]);
}
else if(in[e[i].to])
{
low[x]=min(low[x],dfn[e[i].to]);
}
}
if(dfn[x]==low[x])
{
int y;
cnt++;
do{
y=sta[tp--];
in[y]=0;
tar[y]=cnt;
scc[cnt].push_back(y);
}while(x!=y);
}
}
tarjan缩点:
拓扑排序的思想
代码:
#include<cstdio>
#include<iostream>
#include<cstdlib>
#include<queue>
#define N 100000
using namespace std;
int in[N],dfn[N],low[N],sta[N],tot,tp,cnt,nmb,head[N],nmb2;
int n,m,p[N],h[N],tar[N],inn[N],dist[N];
struct node{
int to,nxt,from;
}e[N<<1],e2[N<<1];
void add(int from,int to)
{
e[++nmb]= (node) {to,head[from],from};
head[from]=nmb;
}
void add2(int from,int to)
{
e2[++nmb2]= (node) {to,h[from],from};
h[from]=nmb2;
}
void tarjan(int x)
{
dfn[x]=low[x]=++tot;
sta[++tp]=x;
in[x]=1;
for(int i=head[x];i;i=e[i].nxt)
{
int v=e[i].to;
if(!dfn[v])
{
tarjan(v);
low[x]=min(low[x],low[v]);
}
else if(in[v])
{
low[x]=min(low[x],dfn[v]);
}
}
if(dfn[x]==low[x])
{
int y;
while(y=sta[tp--])
{
tar[y]=x;
in[y]=0;
if(x==y)break;
p[x]+=p[y];
}
}
}
int topo()
{
queue <int> q;
for(int i=1;i<=n;i++)
if(tar[i]==i&&!inn[i])
{
q.push(i);
dist[i]=p[i];
}
while(q.size())
{
int x=q.front();
q.pop();
for(int i=h[x];i;i=e2[i].nxt)
{
int y=e2[i].to;
dist[y]=max(dist[x]+p[y],dist[y]);
inn[y]--;
if(inn[y]==0)q.push(y);
}
}
int ans=0;
for(int i=1;i<=n;i++)ans = max(ans,dist[i]);
return ans;
}
int main()
{
scanf("%d%d",&n,&m);
for(int i=1;i<=n;i++)scanf("%d",&p[i]);
for(int i=1,x,y;i<=m;i++)
{
scanf("%d%d",&x,&y);
add(x,y);
}
for(int i=1;i<=n;i++) if(!dfn[i])tarjan(i);
for(int i=1;i<=m;i++)
{
int x=tar[e[i].from] , y=tar[e[i].to];
if(x!=y)
{
add2(x,y);
inn[y]++;
}
}
printf("%d\n",topo());
return 0;
}
透彻tarjan的更多相关文章
- HDOJ迷宫城堡(判断强连通 tarjan算法)
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)Total Submission( ...
- LCA 最近公共祖先 tarjan离线 总结 结合3个例题
在网上找了一些对tarjan算法解释较好的文章 并加入了自己的理解 LCA(Least Common Ancestor),顾名思义,是指在一棵树中,距离两个点最近的两者的公共节点.也就是说,在两个点通 ...
- tarjan算法--求解无向图的割点和桥
1.桥:是存在于无向图中的这样的一条边,如果去掉这一条边,那么整张无向图会分为两部分,这样的一条边称为桥 也就是说 无向连通图中,如果删除某边后,图变成不连通,则称该边为桥 2.割点:无向连通图中,如 ...
- tarjan 算法应用
主要讲证明,流程倒是也有 然后发现自己并不会严谨证明 其实后面一些部分流程还是挺详细 本来这篇blog叫做"图论部分算法证明",然后发现OI中的图论想完全用数学上的方法证明完全超出 ...
- HDU4738 tarjan割边|割边、割点模板
题目:http://acm.hdu.edu.cn/showproblem.php?pid=4738 坑点: 处理重边 图可能不连通,要输出0 若求出的结果是0,则要输出1,因为最少要派一个人 #inc ...
- bzoj 1179[Apio2009]Atm (tarjan+spfa)
题目 输入 第一行包含两个整数N.M.N表示路口的个数,M表示道路条数.接下来M行,每行两个整数,这两个整数都在1到N之间,第i+1行的两个整数表示第i条道路的起点和终点的路口编号.接下来N行,每行一 ...
- tarjan讲解(用codevs1332(tarjan的裸题)讲解)
主要借助这道比较裸的题来讲一下tarjan这种算法 tarjan是一种求解有向图强连通分量的线性时间的算法.(用dfs来实现) 如果两个顶点可以相互通达,则称两个顶点强连通.如果有向图G的每两个顶点都 ...
- NOIP2009最优贸易[spfa变形|tarjan 缩点 DP]
题目描述 C 国有 n 个大城市和 m 条道路,每条道路连接这 n 个城市中的某两个城市.任意两个 城市之间最多只有一条道路直接相连.这 m 条道路中有一部分为单向通行的道路,一部分 为双向通行的道路 ...
- Tarjan
//求强连通分量 void uni(int x,int y){ if (rank[x]<rank[y]){ fa[x]=y; size[y]+=size[x]; }else{ rank[x]+= ...
随机推荐
- 【记忆化搜索】Happy Happy Prime Prime
题目描述 RILEY VASHTEE: [reading from display] Find the next number in the sequence:313 331 367 ...? Wha ...
- 手动部署k8s-prometheus
简介 Prometheus 最初是 SoundCloud 构建的开源系统监控和报警工具,是一个独立的开源项目,于2016年加入了 CNCF 基金会,作为继 Kubernetes 之后的第二个托管项目. ...
- golang随机数及pipe
var pipe1 = make(chan int, 1000) func piTest(){ for{ data := <- pipe1 fmt.Printf("get data:% ...
- 使用 js 简单的实现 bind、call 、aplly
Function.prototype._call = function(obj,...arg){ var me = this; var k = Symbol("test"); // ...
- 怎样理解undefined和 null
前言: undefined表示 "未定义", null 表示 "空" 第一步: 一般在变量或属性没有声明或者声明以后没有赋值时, 这个变量的值就是undefin ...
- asp.net core 中hangfire面板的配置及使用
1.定义校验授权类DyDashboardAuthorizationFilter /// <summary> /// Hangfire仪表盘配置授权 /// </summary> ...
- element-ui表格带复选框使用方法及默认选中方法
一.实现多选:步骤1:在表格中添加一列 步骤2:在data中定义以及数组用来存储选中的元素.例如:multipleSelection:[] selection-change方法用户实时监听选中元素 实 ...
- js对象中属性调用.和[] 两种方式的区别
JS 调用属性一般有两种方法——点和中括号的方法. 标准格式是对象.属性(不带双引号),注意一点的是:js对象的属性,key标准是不用加引号的,加也可以,特别的情况必须加,如果key数字啊,表达式啊等 ...
- ssh-copy-id三步实现SSH无密码登录和ssh常用命令
第一步:在本地机器上使用ssh-keygen产生公钥私钥对 $ ssh-keygen 第二步:用ssh-copy-id将公钥复制到远程机器中 $ ssh-copy-id -i .ssh/id_rsa ...
- printf固定一行打印倒计时的实现
@2019-07-15 [小记] #include<stdlib.h> #include <stdio.h> #include <time.h> #include ...