还有五天就是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代码的更多相关文章

  1. tarjan讲解(用codevs1332(tarjan的裸题)讲解)

    主要借助这道比较裸的题来讲一下tarjan这种算法 tarjan是一种求解有向图强连通分量的线性时间的算法.(用dfs来实现) 如果两个顶点可以相互通达,则称两个顶点强连通.如果有向图G的每两个顶点都 ...

  2. POJ 1144 Network(Tarjan求割点)

    Network Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 12707   Accepted: 5835 Descript ...

  3. 强连通分量(tarjan求强连通分量)

    双DFS方法就是正dfs扫一遍,然后将边反向dfs扫一遍.<挑战程序设计>上有说明. 双dfs代码: #include <iostream> #include <cstd ...

  4. [NOIP2009][LuoguP1073] 最优贸易 - Tarjan,拓扑+DP

    Description&Data 题面:https://www.luogu.org/problemnew/show/P1073 Solution Tarjan对联通块缩点,在DAG上按照拓扑序 ...

  5. 利用Tarjan算法解决(LCA)二叉搜索树的最近公共祖先问题——数据结构

    相关知识:(来自百度百科)  LCA(Least Common Ancestors) 即最近公共祖先,是指在有根树中,找出某两个结点u和v最近的公共祖先. 例如: 1和7的最近公共祖先为5: 1和5的 ...

  6. Tarjan模板题——牛的舞会

    题目描述 约翰的N (2 <= N <= 10,000)只奶牛非常兴奋,因为这是舞会之夜!她们穿上礼服和新鞋子,别 上鲜花,她们要表演圆舞. 只有奶牛才能表演这种圆舞.圆舞需要一些绳索和一 ...

  7. POJ 1236 Network of Schools(tarjan)题解

    题意:一个有向图.第一问:最少给几个点信息能让所有点都收到信息.第二问:最少加几个边能实现在任意点放信息就能传遍所有点 思路:把所有强连通分量缩成一点,然后判断各个点的入度和出度 tarjan算法:问 ...

  8. HDU 4685 Prince and Princess 二分图匹配+tarjan

    Prince and Princess 题目连接: http://acm.hdu.edu.cn/showproblem.php?pid=4685 Description There are n pri ...

  9. POJ 3648 Wedding(2-SAT的模型运用+DFS | Tarjan)

    Wedding Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 10427   Accepted: 3170   Specia ...

随机推荐

  1. 解决通过Nginx转发的服务请求头header中含有下划线的key,其值取不到的问题

    1. 问题 由于在http请求头的头部中设置了一些自定义字段,刚好这些字段中含有下划线,比如bundle_name这种,后端在进去获取头部信息时,发现取不到对应的值 2. 原因及解决办法 分析 首先看 ...

  2. Docker容器启动lnmp环境下的mysql服务时报"MySQL server PID file could not be found"错误解决办法

    我在自己的mac笔记本上装了一个docker,并在docker容器中安装了lnmp环境,经常会遇到在使用"lnmp restart"命令启动lnmp服务的时候,mysql服务启动失 ...

  3. 【iCore4 双核心板_ARM】例程三十五:HTTP_IAP_ARM实验——更新升级STM32

    实验现象: 核心代码: int main(void) { led.initialize(); //LED³õʼ»¯ key.initialize(); if(ARM_KEY_STATE == KEY ...

  4. 光纤网卡、HBA卡和RAID卡的区别(图)

    原文地址:http://wenku.baidu.com/link?url=suuaTXbO_HXeNvuEfi8_RhRAfhQdoZ854lEK4K6LKprgQwwuxA-i3ItwPn7BBBK ...

  5. winscp的root连接ubuntu“拒绝访问”的解决方法

    转载:https://www.cnblogs.com/weizhxa/p/10098640.html 解决: 1.修改ssh配置文件:sudo vim etc/ssh/sshd_config 在#Pe ...

  6. ML 激励函数 Activation Function (整理)

    本文为内容整理,原文请看url链接,感谢几位博主知识来源 一.什么是激励函数 激励函数一般用于神经网络的层与层之间,上一层的输出通过激励函数的转换之后输入到下一层中.神经网络模型是非线性的,如果没有使 ...

  7. Dedecms判断当前栏目下是否有子栏目

    使用dedecms建网站,有时为了某种功能的需要,需要通过代码判断当前栏目下是否有子栏目,如果有,显示一种样式,如果没有,显示另一种样式. dedecms判断当前栏目下是否有子栏目可使用以下的代码进行 ...

  8. iOS 调试大法

    本文转载至 http://www.jianshu.com/p/d19e19a91071 0.笨办法 看变量.对象?NSLog+重新编译运行:改某对象?改源码+重新编译运行:隔离某个方法?在方法中写 r ...

  9. 手写LRU算法

    import java.util.LinkedHashMap; import java.util.Map; public class LRUCache<K, V> extends Link ...

  10. jquery实现同时展示多个tab标签+左右箭头实现来回滚动(美化版增加删除按钮)

    闲聊 前段时间小颖分享了:jquery实现同时展示多个tab标签+左右箭头实现来回滚动文章,引入项目后,我们的组长说样子太丑了,小颖觉得还好啊,要不大家评评理,看下丑不丑?无图无真相,来上图: 看吧其 ...