tarjan

 #include <cstdio>
#include <cstdlib>
#include <cmath>
#include <cstring>
#include <string>
#include <algorithm>
#include <set>
#include <map>
#include <queue>
#include <iostream>
using namespace std; #define ll long long const int maxn=1e4+;
const int inf=1e9;
const double eps=1e-; struct node
{
int d;
node *to;
}*e[maxn]; int id,dfn[maxn],low[maxn],tot_st,st[maxn],m,group[maxn];
bool vis[maxn],vis_st[maxn]; /**
id:编号 每增加一个点,++id
每增加一个点,加入栈中
low:点的编号
dfn:点以及后续点通过一条边能到的最小编号点的编号 同一个类 dfn[d]=low[d] 栈中,第x个数d到栈顶 任意点的low值为dfn[d]
st:栈 若点变为在一个类中时,从栈中弹出
vis_st : 当点还未标记到类中时,可以使用 m:类的个数
group:每个点所在的类
**/ void tarjan(int d)
{
int dd;
vis[d]=;
dfn[d]=low[d]=++id;
st[++tot_st]=d;
node *p=e[d];
while (p)
{
dd=p->d;
if (!vis[dd])
{
tarjan(dd);
low[d]=min(low[d],low[dd]);
}
else if (!vis_st[dd])
low[d]=min(low[d],dfn[dd]);
p=p->to;
}
if (dfn[d]==low[d])
{
m++;
int g=tot_st;
while (st[tot_st]!=d)
{
group[st[tot_st]]=m;
vis_st[st[tot_st]]=;
tot_st--;
}
group[st[tot_st]]=m;
vis_st[st[tot_st]]=;
tot_st--;
g-=tot_st; ///类的大小
}
} int main()
{
node *p;
int n,q,x,y,i;
scanf("%d%d",&n,&q);
while (q--)
{
scanf("%d%d",&x,&y);
///注意单边还是双边
p=new node();
p->d=y;
p->to=e[x];
e[x]=p;
}
for (i=;i<=n;i++)
if (!vis[i])
tarjan(i);
return ;
}
/* */

luogu P1726 上白泽慧音

 #include <cstdio>
#include <cstdlib>
#include <cmath>
#include <cstring>
#include <string>
#include <algorithm>
#include <set>
#include <map>
#include <queue>
#include <iostream>
using namespace std; #define ll long long const int maxn=1e4+;
const int inf=1e9;
const double eps=1e-; struct node
{
int d;
node *to;
}*e[maxn]; int id,dfn[maxn],low[maxn],tot_st,st[maxn],m,group[maxn]; ///m:类的个数
bool vis[maxn],vis_st[maxn]; ///st:栈,存储未被'类‘标签的点 int ind,maxg=,md; void tarjan(int d)
{
int dd;
vis[d]=;
dfn[d]=low[d]=++id;
st[++tot_st]=d;
node *p=e[d];
while (p)
{
dd=p->d;
if (!vis[dd])
{
tarjan(dd);
low[d]=min(low[d],low[dd]);
}
else if (!vis_st[dd])
low[d]=min(low[d],dfn[dd]);
p=p->to;
}
if (dfn[d]==low[d])
{
m++;
int g=tot_st,mind=inf;
while (st[tot_st]!=d)
{
group[st[tot_st]]=m;
mind=min(mind,st[tot_st]);
vis_st[st[tot_st]]=;
tot_st--;
}
group[st[tot_st]]=m;
mind=min(mind,st[tot_st]);
vis_st[st[tot_st]]=;
tot_st--;
g-=tot_st;
if (maxg<g || (maxg==g && mind<md))
ind=m,maxg=g,md=mind;
}
} int main()
{
node *p;
int n,q,x,y,z,i;
scanf("%d%d",&n,&q);
while (q--)
{
scanf("%d%d%d",&x,&y,&z);
p=new node();
p->d=y;
p->to=e[x];
e[x]=p;
if (z==)
{
p=new node();
p->d=x;
p->to=e[y];
e[y]=p;
}
}
for (i=;i<=n;i++)
if (!vis[i])
tarjan(i);
printf("%d",maxg);
bool v=;
for (i=;i<=n;i++)
if (group[i]==ind)
{
if (!v)
printf("\n"),v=;
else
printf(" ");
printf("%d",i);
}
return ;
}
/* */

luogu P3387 【模板】缩点

 #include <cstdio>
#include <cstdlib>
#include <cmath>
#include <cstring>
#include <string>
#include <algorithm>
#include <set>
#include <map>
#include <queue>
#include <iostream>
using namespace std; #define ll long long const int maxn=1e4+;
const int inf=1e9;
const double eps=1e-; /*
题目描述
给定一个n个点m条边有向图,每个点有一个权值,求一条路径,使路径经过的点权值之和最大。你只需要求出这个权值和。
允许多次经过一条边或者一个点,但是,重复经过的点,权值只计算一次。 第一行,n,m
第二行,n个整数,依次代表点权
第三至m+2行,每行两个整数u,v,表示u->v有一条有向边 共一行,最大的点权之和。 2 2
1 1
1 2
2 1 2
*/ struct node
{
int d;
node *to;
}*e[maxn],*gr[maxn]; int id,dfn[maxn],low[maxn],tot_st,st[maxn],m,group[maxn];
bool vis[maxn],vis_st[maxn];
int v[maxn],ans[maxn];/// /**
id:编号 每增加一个点,++id
每增加一个点,加入栈中
low:点的编号
dfn:点以及后续点通过一条边能到的最小编号点的编号 同一个类 dfn[d]=low[d] 栈中,第x个数d到栈顶 任意点的low值为dfn[d]
st:栈 若点变为在一个类中时,从栈中弹出
vis_st : 当点还未标记到类中时,可以使用 m:类的个数
group:每个点所在的类
**/ void tarjan(int d)
{
int dd;
vis[d]=;
dfn[d]=low[d]=++id;
st[++tot_st]=d;
node *p=e[d];
while (p)
{
dd=p->d;
if (!vis[dd])
{
tarjan(dd);
low[d]=min(low[d],low[dd]);
}
else if (!vis_st[dd])
low[d]=min(low[d],dfn[dd]);
p=p->to;
}
if (dfn[d]==low[d])
{
m++;
while (st[tot_st]!=d)
{
group[st[tot_st]]=m; ///
vis_st[st[tot_st]]=;
tot_st--;
}
group[st[tot_st]]=m; ///
vis_st[st[tot_st]]=;
tot_st--;
}
} void dfs(int d)
{
node *p=gr[d];
int dd,add=;
vis[d]=;
while (p)
{
dd=p->d;
if (!vis[dd])
dfs(dd);
add=max(add,ans[dd]); ///点d到达下一个点,最大的值 千万注意这个是放在外面的
p=p->to;
}
ans[d]+=add;
} int main()
{
node *p,*r;
int n,q,x,y,i,d;
scanf("%d%d",&n,&q); for (i=;i<=n;i++) ///点权
scanf("%d",&v[i]); while (q--)
{
scanf("%d%d",&x,&y);
///注意单边还是双边
p=new node();
p->d=y;
p->to=e[x];
e[x]=p;
}
for (i=;i<=n;i++)
if (!vis[i])
tarjan(i); for (i=;i<=n;i++)
{
ans[group[i]]+=v[i]; ///同一类,能互相访问所有的点
p=e[i];
while (p)
{
d=p->d;
if (group[i]!=group[d])
{
r=new node(); ///变量名要有区分
r->d=group[d];
r->to=gr[group[i]];
gr[group[i]]=r; // printf("%d %d\n",group[i],group[d]);
}
p=p->to;
}
} ///tarjan+缩点后无环
memset(vis,,sizeof(vis));
for (i=;i<=n;i++)
if (!vis[i])
dfs(i);
int maxa=;
for (i=;i<=n;i++)
maxa=max(maxa,ans[i]);
printf("%d",maxa);
return ;
}
/*
3 2
1 2 3
1 2
1 3
*/

luogu P3388 【模板】割点(割顶)

tarjan模板的更多相关文章

  1. 图论算法-Tarjan模板 【缩点;割顶;双连通分量】

    图论算法-Tarjan模板 [缩点:割顶:双连通分量] 为小伙伴们总结的Tarjan三大算法 Tarjan缩点(求强连通分量) int n; int low[100010],dfn[100010]; ...

  2. UOJ #146. 【NOIP2015】信息传递 连通分量 tarjan模板题

    http://uoj.ac/problem/146 题解:强连通分量 tarjan模板题.同时试了一下codeblock #include<bits/stdc++.h> using nam ...

  3. 学渣乱搞系列之Tarjan模板合集

    学渣乱搞系列之Tarjan模板合集 by 狂徒归来 一.求强连通子图 #include <iostream> #include <cstdio> #include <cs ...

  4. 洛谷1726 上白泽慧音 tarjan模板

    题目描述 在幻想乡,上白泽慧音是以知识渊博闻名的老师.春雪异变导致人间之里的很多道路都被大雪堵塞,使有的学生不能顺利地到达慧音所在的村庄.因此慧音决定换一个能够聚集最多人数的村庄作为新的教学地点.人间 ...

  5. 算法问题实战策略 MEETINGROOM 附一份tarjan模板

    地址 https://algospot.com/judge/problem/read/MEETINGROOM 解答  2-sat 代码样例过了 没有ac. 我又没有正确代码对拍..... 已确认是输出 ...

  6. POJ 2186:Popular Cows Tarjan模板题

    Popular Cows Time Limit: 2000MS   Memory Limit: 65536K Total Submissions: 25945   Accepted: 10612 De ...

  7. Tarjan 模板,高级并查集

    第一个模板有误!!!! 请见谅!!! 要怪就怪HDU吧,竟然让我过了 第二个模板是正确的.请翻到下面看更新 HDU 1269 评论区居然有人说用并查集过了,其实回想一下 求无向图的连通分量,就是并查集 ...

  8. 强连通分量(Tarjan)模板

    贴模板,备忘. 模板1: #include<iostream> #include<cstring> #include<cmath> #include<cstd ...

  9. HDU:1269-迷宫城堡(tarjan模板)

    迷宫城堡 Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others) Problem Descri ...

随机推荐

  1. 【原】Java学习笔记006 - 流程控制

    package cn.temptation; public class Sample01 { public static void main(String[] args) { // 需求:写一万次&q ...

  2. python_库学习_02_微信自动回复机器人

    一.python发展的趋势日益庞大,微信也有对应的库itchat.这次的实例做做成可在任意电脑运行的微信自动回复机器人exe.文件. 二.完成这个小应用我们需要装一些库,, itchat:这个东东不出 ...

  3. (一)走进Metasploit渗透测试框架

    渗透测试的流程 渗透测试是一种有目的性的,针对目标机构计算机系统安全的检测评估方法,渗透测试的主要目的是改善目标机构的安全性.渗透测试各个阶段的基本工作: 1.前期交互阶段 在这个阶段,渗透测试工程师 ...

  4. python中创建虚拟环境

    # virtualenv 虚拟环境安装 pip install virtualenv # 创建虚拟环境        virtualenv [虚拟环境名称] # 进入虚拟环境 windows : 进入 ...

  5. WIN提权总结【本地存档-转载】

    [ web提权 ] 1.能不能执行cmd就看这个命令:net user,net不行就用net1,再不行就上传一个net到可写可读目录,执行/c c:\windows\temp\cookies\net1 ...

  6. 转://ORA-00603,ORA-27501,ORA-27300,ORA-27301,ORA-27302故障案例一则

    背景介绍: 这是一套windows的rac系统.数据库后台日志报ORA-00474:SMON process terminated with error.接着报ORA-00603,ORA-27501, ...

  7. GIT归纳整理

    1. 将repo_a的分支提交到repo_b分支 repo_a:表示原始git库地址:repo_b:表示新增的git库地址. git remote add new_remote repo_b:new_ ...

  8. Linux内存管理 (19)总结内存管理数据结构和API

    专题:Linux内存管理专题 关键词:mm.vaddr.VMA.page.pfn.pte.paddr.pg_data.zone.mem_map[]. 1. 内存管理数据结构的关系图 在大部分Linux ...

  9. JDK1.8源码(十)——java.util.LinkedHashSet类

    同 HashSet 与 HashMap 的关系一样,本篇博客所介绍的 LinkedHashSet 和 LinkedHashMap 也是一致的.在 JDK 集合框架中,类似 Set 集合通常都是由对应的 ...

  10. Educational Codeforces Round 62 (Rated for Div. 2) Solution

    最近省队前联考被杭二成七南外什么的吊锤得布星,拿一场Div. 2恢复信心 然后Div.2 Rk3.Div. 1+Div. 2 Rk9,rating大涨200引起舒适 现在的Div. 2都怎么了,最难题 ...