拓扑排序最长链-P3119 [USACO15JAN]草鉴定Grass Cownoisseur

https://www.luogu.org/problem/show?pid=3119
本来我是来练习tarjan的,结果tarjan部分直接copy了,反而拓扑排序部分想了好久;
这道题SZB大神两次就AC;
但我等到AC,写好题解就只能洗洗睡了;
唉~
差距怎么这么大呢?;
这道题的题意就说,你可以改变一条边的方向,去找到一个环,让环上的点数最大;
网上的题解,大多都在嚷嚷tarjan+拓扑排序最长链;
我先讲讲什么是拓扑排序最长链把;


这里写图片描述
很显然啊,上面的图里,1~3的最长链是3;
我们考虑一下最朴素的dfs;
我们从1开始,先搜索到了3;
这个时候我们把1~3的最长链更新为 1-3,就是2个节点;
假如3出度有好多,那么凡是3后面的点我们都要遍历一边;
然后遍历完3,我发现 1~3的最长链不是1-3而是1-2-3;
原先的1~3最长链的节点个数2被更新为3;
这个时候我们发现原来3连出去的点,他们与1的最长链都不是最优的;
所以我们又要dfs一遍;
这样太烦了;
那怎么办呢?
看到这里,我想您一定知道什么是拓扑排序最长链了;
对啊,假如我们搜索到3的时候先不去往后面搜索,先去遍历2;
这样1~3的最长链会被及时更新,3后面的节点就不用重复更新了;
其实这样就是按照拓扑排序的顺序去遍历节点啊,不断找入度为0的节点去更新其它节点;
这就是拓扑排序最长链


这道题就简单了啊;
我先缩点一下,让这个有环图变成有向无环图;
然后用一个dfs去算出那些点可以到达1;那些点会从1到达;
分别算出这些点到1的最长链,然后枚举每一条边,看看把这条边反一下,加上两端到1的最长链然后更新ans就好啦;
很显然啊,这两条链不会重复,因为他们的方向是不同的;
我的超级优美的代码,60行!;

超级无敌大压行!!!!

#include<cstdio>//cfb
#include<iostream>
#include<cstring>
using namespace std;
struct cs{int to,next;}a[100001];          //lin[i]是i再那个分量里面  sum[i]就是第i个分量有几个点 d[i]是当前分量i的入度 
int head[100001],low[100001],tt[100001],q[100001],lin[100001],cc[100001][2],sum[100001],A[100001][1],d[100001];
bool in[100001],AA[100001][2];//AA[i][0]表示1是否可以到i,[1]是i是否可以到j;A[i][0/1]即他们的最长链 
int ll,n,m,x,y,z,t,nn,l,r,ans;
void init(int x,int y){a[++ll].to=y; a[ll].next=head[x]; head[x]=ll;}
void dfs(int x){
    tt[x]=++t; low[x]=t; q[++q[0]]=x; in[x]=1;
    for(int k=head[x];k;k=a[k].next){
        if(!tt[a[k].to])dfs(a[k].to);
        if(in[a[k].to])low[x]=min(low[x],low[a[k].to]); 
    }
    if(low[x]==tt[x]){
        nn++;
        while(1){
            in[q[q[0]]]=0;
            lin[q[q[0]]]=nn;    
            q[0]--; sum[nn]++;
            if(q[q[0]+1]==x)break;
        }
    }
}
void make(int x,int num){//然后用一个dfs去算出那些点可以到达1;那些点会从1到达;
    in[x]=1; AA[x][num]=1;
    for(int k=head[x];k;k=a[k].next){d[a[k].to]++; if(!in[a[k].to])make(a[k].to,num);}
}
void TP(int num){//拓扑排序
    r=1; q[1]=lin[1]; A[lin[1]][num]=0; 
    make(lin[1],num); 
    while(r>l){
        x=q[++l];
        for(int k=head[x];k;k=a[k].next){
            A[a[k].to][num]=max(A[a[k].to][num],A[x][num]+sum[a[k].to]);
            d[a[k].to]--;
            if(!d[a[k].to])q[++r]=a[k].to;
        }
    }
}
void S(){
    memset(q,0,sizeof q);memset(head,0,sizeof head);
    memset(d,0,sizeof d);memset(in,0,sizeof in);
    ll=0; r=l=0;
}
int main()
{
    scanf("%d%d",&n,&m);
    for(int i=1;i<=m;i++){scanf("%d%d",&cc[i][0],&cc[i][1]);init(cc[i][0],cc[i][1]);}
    for(int i=1;i<=n;i++)if(!tt[i])dfs(i);
    S(); for(int i=1;i<=m;i++){x=cc[i][0]; y=cc[i][1]; if(lin[x]!=lin[y])init(lin[x],lin[y]);} TP(0);
    S(); for(int i=1;i<=m;i++){x=cc[i][0]; y=cc[i][1]; if(lin[x]!=lin[y])init(lin[y],lin[x]);} TP(1);
    for(int i=1;i<=m;i++){
        x=lin[cc[i][0]]; y=lin[cc[i][1]];
        if(x==y||!AA[y][0]||!AA[x][1])continue;
        ans=max(ans,A[y][0]+A[x][1]);
    }
    printf("%d",ans+sum[lin[1]]);
}

转载于:https://www.cnblogs.com/largecube233/p/6797932.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/372872.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

IBM JVM调整– gencon GC策略

本文将向您详细介绍从Java虚拟机&#xff08;例如HotSpot或JRockit&#xff09;迁移到IBM JVM时重要的Java堆空间调整注意事项。 该调整建议基于我为我的一个IT客户端执行的最新故障排除和调整任务。 IBM JVM概述 正如您可能从其他文章中看到的那样&#xff0c;IBM JVM在某些方…

懒惰的JSF Primefaces数据表分页–第2部分

页面代码非常简单&#xff0c;没有复杂性。 检查“ index.xhtml”代码&#xff1a; <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns"http://www…

java实现报表_用存储过程和 JAVA 写报表数据源有什么弊端?

用存储过程和 JAVA 写报表数据源有什么弊端&#xff1f;跟着小编一起来一看一下吧&#xff01;我们在报表开发中经常会使用存储过程准备数据&#xff0c;存储过程支持分步计算&#xff0c;可以实现非常复杂的计算逻辑&#xff0c;为报表开发带来便利。所以&#xff0c;报表开发…

SpringMVC学习笔记整理

SpringMVC学习笔记 以下是我整理的SpringMVC学习笔记&#xff1a; 导入jar包 一&#xff1a;springmvc工作流程。 ①. servlet容器初始化一个request请求 ②. DispatcherServlet分发器负责发送请求到映射器. ③. despatcherServlet把请求交给处理器映射Mapping&…

springboot2 使用hikaridatasource 并测试_基于Spring Boot 2.x的后端管理网站脚手,源码免费分享...

基于Spring Boot 2.x 的 Material Design 的后端管理网站脚手架 &#xff1a;提供权限认证 用户管理 菜单管理 操作日志 等常用功能去繁就简 重新出发基于Spring Boot 集成一些常用的功能&#xff0c;你只需要基于它做些简单的修改即可。功能列表&#xff1a;权限认证权限管理用…

测试驱动开发–双赢策略

敏捷从业人员谈论测试驱动开发 &#xff08;TDD&#xff09;&#xff0c;所以许多关心代码质量和可操作性的开发人员也是如此。 我曾几何时&#xff0c;不久前设法阅读了有关TDD的文章。 据我了解&#xff0c;TDD的关键是&#xff1a; 编写测试&#xff0c;但失败 代码&#x…

设计模式学习(三)——装饰器模式

前言 距离上一次正儿八经地写随笔已经有一段时间了&#xff0c;虽然2月10号有一篇关于泛型的小记&#xff0c;但是其实只是简单地将自己的学习代码贴上来&#xff0c;为了方便后续使用时查阅&#xff0c;并没有多少文字和理解感悟。之所以在今天觉得有必要写点东西&#xff0c;…

PCL学习八叉树

建立空间索引在点云数据处理中有着广泛的应用&#xff0c;常见的空间索引一般 是自顶而下逐级划分空间的各种空间索引结构&#xff0c;比较有代表性的包括BSP树&#xff0c;KD树&#xff0c;KDB树&#xff0c;R树&#xff0c;四叉树&#xff0c;八叉树等索引结构&#xff0c;而…

Android实现自定义带文字和图片的Button

在Android开发中经常会需要用到带文字和图片的button&#xff0c;下面来讲解一下常用的实现办法。 一.用系统自带的Button实现 最简单的一种办法就是利用系统自带的Button来实现&#xff0c;这种方式代码量最小。在Button的属性中有一个是drawableLeft&#xff0c;这个 属性可以…

mysql语句中的注释方法_MySQL语句注释方式简介

MySQL支持三种注释方式&#xff1a;1.从‘#字符从行尾。2.从‘-- 序列到行尾。请注意‘-- (双破折号)注释风格要求第2个破折号后面至少跟一个空格符(例如空格、tab、换行符等等)。3.从/*序列到后面的*/序列。结束序列不一定在同一行中&#xff0c;因此该语法允许注释跨越多行。…

android框架----下沉文字Titanic的使用

Titanic is a simple illusion obtained by applying an animated translation on the TextView TextPaint Shaders matrix. Titanic的使用 Titanic的使用&#xff0c;项目结构如下&#xff1a; 一、下载Titanic并且部署到项目中 Titanic的项目地址&#xff1a; https://github…

linux 自动安装mysql_Linux安装mysql

一、下载这里我创建了一目录software用于存放我们待会要下载的mysql包&#xff0c;先去到该目录命令&#xff1a;cd /software命令&#xff1a;wget http://mirrors.sohu.com/mysql/MySQL-5.7/mysql-5.7.17-linux-glibc2.5-x86_64.tar下载完成后&#xff0c;你会在software这个…

Animation用法

测试代码及说明&#xff1a; <!DOCTYPE html> <html lang"en-US"> <head><meta charset"UTF-8"><title>Simple CSS3 Animation</title><style type"text/css">#demo {position: absolute;left: 30%;t…

mysql备份 where_MySQL备份与还原

1.mysqldumpmysqlbinlog介绍mysqldump备份结合binlog日志恢复。MySQL备份一般采取全库备份加日志备份的方式&#xff0c;例如每天执行一次全备份&#xff0c;每小时执行一次二进制日志备份&#xff0c;这样在MySQL故障后可以使用全备份和日志备份将数据恢复到最后一个二进制日志…

JMeter:负载测试关系数据库

Apache JMeter是完全使用Java编写的性能测试工具。 可以在请求/响应模型上运行的任何应用程序都可以使用JMeter进行负载测试。 关系数据库也不例外&#xff1a;接收sql查询&#xff0c;执行它们并返回执行结果。 我将向您展示使用JMeter的图形用户界面设置测试方案有多么容易。…

new: Set up a window

Nehe的教程确实太老了&#xff0c;不过我认为它也能够让我了解OpenGL3.2以前的管线渲染模式&#xff0c;即使它在现在已经不常见了。因为想要了解&#xff0c;所以我还是会看完Nehe的教程。 现在这是一个新的教程 - JoeyDeVries的教程&#xff0c;可以说是网上最好的OpenGL教程…

Python全栈开发:socket

Socket socket通常也称作"套接字"&#xff0c;用于描述IP地址和端口&#xff0c;是一个通信链的句柄&#xff0c;应用程序通常通过"套接字"向网络发出请求或者应答网络请求。 socket起源于Unix&#xff0c;而Unix/Linux基本哲学之一就是“一切皆文件”&…

NetBeans 7.1:创建自定义提示

我已经在帖子中介绍了一些我最喜欢的NetBeans提示 &#xff0c;这些信息是用于使Java代码现代化的七个NetBeans提示和七个不可或缺的NetBeans Java提示 。 这两个帖子中涉及的十四个提示仅占NetBeans支持的“即开即用”提示总数的一小部分。 但是&#xff0c;由于NetBeans 7.1使…

qregexp括号匹配_转:Qt的正则表达式和QRegExp

考虑一下我们经常遇到的问题&#xff0c;比如gemfield想从青岛之光读书(www.civilnet.cn/book)中找一个关键的电话号码&#xff0c;通常第一步就是将书中所有的电话号码查找出来放在手边。那么怎么拟定查询条件呢&#xff1f;电话的格式有如下几种&#xff1a;01088888888010 8…

具有Tron效果的JavaFX 2 Form

这是一个具有TRON效果的简单JavaFX登录表单。 在此示例中&#xff0c;我使用CSS设置TextField和Button的样式。 这是CSS和Effect代码的片段&#xff1a; .text-field{-fx-background-color: transparent;-fx-border-color: #00CCFF;-fx-text-fill: white; }.password-field{-fx…