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. Vue双向绑定原理,教你一步一步实现双向绑定

    当今前端天下以 Angular.React.vue 三足鼎立的局面,你不选择一个阵营基本上无法立足于前端,甚至是两个或者三个阵营都要选择,大势所趋. 所以我们要时刻保持好奇心,拥抱变化,只有在不断的变 ...

  2. 《Effective Java中文版第二版》读书笔记

    说明 这里是阅读<Effective Java中文版第二版>的读书笔记,这里会记录一些个人感觉稍微有些重要的内容,方便以后查阅,可能会因为个人实力原因导致理解有误,若有发现欢迎指出.一些个 ...

  3. Thread中的join()方法

    package com.qjc.thread; public class JoinExcemple { // join方法就是用来同步的 public static void main(String[ ...

  4. kernel笔记——库文件与系统调用

    库文件 先从我们熟悉的c库入手,理解系统调用(system call).c代码中调用printf函数,经历了以下调用过程:   最终输出的功能由内核中write调用完成,c库封装了系统调用. 对于以下 ...

  5. 【转】Vue.js中 watch 的高级用法

    假设有如下代码: <div> <p>FullName: {{fullName}}</p> <p>FirstName: <input type=&q ...

  6. 从开始到头皮炸裂的python第5天

    头皮炸裂的一天从学到一个新的数据类型开始,这个数据类型的新成员叫做字典,基本的格式为data={键:值,键:值},info.keys()表示所有的键,info.values()表示所有的值,info. ...

  7. Push rejected: Push to origin/master was rejected错误解决方案

    解决方案如下: 1.切换到自己项目所在的目录,右键选择GIT BASH Here,Idea中可使用Alt+F12 2.在terminl窗口中依次输入命令: git pull git pull orig ...

  8. 图表插件Highcharts的动态化赋值,实现图表数据的动态化设置显示

    在很早之前就介绍过图表插件Highcharts的使用了,在2014年的随笔<基于MVC4+EasyUI的Web开发框架经验总结(4)--使用图表控件Highcharts>,这里基本上都介绍 ...

  9. HTML/CSS 速写神器 Emmet语法

    Emmet 是高效.快速编写 HTML 和 CSS 代码的一种插件,如果还不了解,请戳Emmet — the essential toolkit for web-developers,再根据你使用的编 ...

  10. docker 小技巧 docker network create br-name 指定IP地址

    在某些情况下,使用 docker network create br-name 命令创建网络的时候,会创建一个新的网桥,该网桥的默认IP地址为172.18.0.0\16(或相临的IP地址段) 这个ip ...