问题描述

LG3119


题解

显然,如果有个环,一定是全部走完的。

所以缩点,缩出一个 \(\mathrm{DAG}\) 。

只能走一次反向,于是在正图和反图上各跑一次,枚举边,取 \(\mathrm{max}\) 即可。


\(\mathrm{Code}\)

#include<bits/stdc++.h>
using namespace std; #define maxn 100007 template <typename Tp>
void read(Tp &x){
x=0;char ch=1;int fh;
while(ch!='-'&&(ch<'0'||ch>'9')) ch=getchar();
if(ch=='-') {
ch=getchar();fh=-1;
}
else fh=1;
while(ch>='0'&&ch<='9'){
x=(x<<1)+(x<<3)+ch-'0';
ch=getchar();
}
x*=fh;
} int n,dfn[maxn],low[maxn];
int m,Head1[maxn],Next1[maxn],to1[maxn],u1[maxn],tot1;
int Head2[maxn],Next2[maxn],to2[maxn],u2[maxn],tot2;
int Head3[maxn],Next3[maxn],to3[maxn],u3[maxn],tot3;
int xx,yy;
int stac[maxn],top,ind,cnt; int sd[maxn],val[maxn];
bitset<maxn>ins;
void tarjan(int x){
dfn[x]=low[x]=++ind;stac[++top]=x;
ins[x]=1;
for(int i=Head1[x];i;i=Next1[i]){
int y=to1[i];
if(dfn[y]) {if(ins[y]) low[x]=min(low[x],dfn[y]);}
else{
tarjan(y);
low[x]=min(low[x],low[y]);
}
}
if(dfn[x]==low[x]){
cnt++;val[cnt]=1;
while(stac[top]!=x){
ins[stac[top]]=0;sd[stac[top]]=cnt;top--;++val[cnt];
}
sd[stac[top]]=cnt;top--;ins[x]=0;
}
} void add1(int x,int y){
to1[++tot1]=y,Next1[tot1]=Head1[x],Head1[x]=tot1,u1[tot1]=x;
} void add2(int x,int y){
to2[++tot2]=y,Next2[tot2]=Head2[x],Head2[x]=tot2,u2[tot2]=x;
} void add3(int x,int y){
to3[++tot3]=y,Next3[tot3]=Head3[x],Head3[x]=tot3,u3[tot3]=x;
} set <pair<int,int> > st; void rebuild(){
for(register int i=1;i<=m;i++){
// if(sd[to1[i]]==0||sd[u1[i]]==0) continue;
int x=sd[u1[i]],y=sd[to1[i]];
if(st.count(make_pair(x,y))||x==y) continue;
st.insert((make_pair(x,y)));
add2(x,y);add3(y,x);
}
} int dis[2][maxn]; void fir(){
memset(dis[0],0xcf,sizeof(dis[0]));
dis[0][sd[1]]=val[sd[1]];queue<int>q;q.push(sd[1]);
while(!q.empty()){
int x=q.front();q.pop();
for(int i=Head2[x];i;i=Next2[i]){
int y=to2[i];
if(dis[0][y]>=dis[0][x]+val[y]) continue;
dis[0][y]=dis[0][x]+val[y];
q.push(y);
}
}
} void sec(){
memset(dis[1],0xcf,sizeof(dis[1]));
dis[1][sd[1]]=val[sd[1]];queue<int>q;q.push(sd[1]);
while(!q.empty()){
int x=q.front();q.pop();
for(int i=Head3[x];i;i=Next3[i]){
int y=to3[i];
if(dis[1][y]>=dis[1][x]+val[y]) continue;
dis[1][y]=dis[1][x]+val[y];
q.push(y);
}
}
} int ans=0; void calc(){
for(register int i=1;i<=tot2;i++){
int x=u2[i],y=to2[i];//错误笔记:写为to2[i],开-Wall之后会有警告。
ans=max(ans,dis[0][y]+dis[1][x]);
}
printf("%d\n",ans-val[sd[1]]);//错误笔记:将sd[1]写为1,所点后1所在的结点不一定是新1号点。
} int main(){
read(n);read(m);
for(register int i=1;i<=m;i++){
read(xx);read(yy);add1(xx,yy);
}
for(register int i=1;i<=n;i++)
if(!dfn[i]) tarjan(i); // puts("********************************");
// printf("%d\n",cnt);
// system("pause");
// puts("********************************"); rebuild();
fir();sec();
calc();
return 0;
}

LG3119 「USACO2015JAN」Grass Cownoisseur的更多相关文章

  1. 「译」JUnit 5 系列:条件测试

    原文地址:http://blog.codefx.org/libraries/junit-5-conditions/ 原文日期:08, May, 2016 译文首发:Linesh 的博客:「译」JUni ...

  2. 「译」JUnit 5 系列:扩展模型(Extension Model)

    原文地址:http://blog.codefx.org/design/architecture/junit-5-extension-model/ 原文日期:11, Apr, 2016 译文首发:Lin ...

  3. JavaScript OOP 之「创建对象」

    工厂模式 工厂模式是软件工程领域一种广为人知的设计模式,这种模式抽象了创建具体对象的过程.工厂模式虽然解决了创建多个相似对象的问题,但却没有解决对象识别的问题. function createPers ...

  4. 「C++」理解智能指针

    维基百科上面对于「智能指针」是这样描述的: 智能指针(英语:Smart pointer)是一种抽象的数据类型.在程序设计中,它通常是经由类型模板(class template)来实做,借由模板(tem ...

  5. 「JavaScript」四种跨域方式详解

    超详细并且带 Demo 的 JavaScript 跨域指南来了! 本文基于你了解 JavaScript 的同源策略,并且了解使用跨域跨域的理由. 1. JSONP 首先要介绍的跨域方法必然是 JSON ...

  6. 「2014-5-31」Z-Stack - Modification of Zigbee Device Object for better network access management

    写一份赏心悦目的工程文档,是很困难的事情.若想写得完善,不仅得用对工具(use the right tools),注重文笔,还得投入大把时间,真心是一件难度颇高的事情.但,若是真写好了,也是善莫大焉: ...

  7. 「2014-3-18」multi-pattern string match using aho-corasick

    我是擅(倾)长(向)把一篇文章写成杂文的.毕竟,写博客记录生活点滴,比不得发 paper,要求字斟句酌八股结构到位:风格偏杂文一点,也是没人拒稿的.这么说来,arxiv 就好比是 paper 世界的博 ...

  8. 「2014-3-17」C pointer again …

    记录一个比较基础的东东-- C 语言的指针,一直让人又爱又恨,爱它的人觉得它既灵活又强大,恨它的人觉得它太过于灵活太过于强大以至于容易将人绕晕.最早接触 C 语言,还是在刚进入大学的时候,算起来有好些 ...

  9. 「2014-3-13」Javascript Engine, Java VM, Python interpreter, PyPy – a glance

    提要: url anchor (ajax) => javascript engine (1~4 articles) => java VM vs. python interpreter =& ...

随机推荐

  1. oracle xmltype + blob + clob

    oracle varchar2最大存储长度为4000,所以当字段长度超限时可尝试存储为blob或xmltype格式 xmltype --1.创建xml表 Create TABLE testxml( i ...

  2. JMeter基础知识系列二

    1.从web服务或其他远程服务的角度来看,Jmeter很像是一款浏览器,但实际他并不是浏览器,Jmeter支持浏览器的部分操作.如:Jmeter不支持hmtl页面中包含的JavaScript脚本.处理 ...

  3. Log4j2之ThreadContext

    简介 系统中使用log4j2作为日志系统,然而在高并发的情况下,多次请求的日志参杂在一起,要跟踪某个用户一次的请求操作所有日志是很麻烦的.幸运的是log4j中有相应的解决方案. NDC和MDC NDC ...

  4. Dubbo 一些你不一定知道但是很好用的功能

    dubbo功能非常完善,很多时候我们不需要重复造轮子,下面列举一些你不一定知道,但是很好用的功能: 直连Provider 在开发及测试环境下,可能需要绕过注册中心,只测试指定服务提供者,这时候可能需要 ...

  5. IT兄弟连 Java语法教程 流程控制语句 控制循环结构1

    Java语言没有提供goto语句来控制程序的跳转,这种做法提高了程序流程控制的可读性,但降低了程序流程控制的灵活性.为了弥补这种不足,Java提供了continue和break来控制循环结构.除此之外 ...

  6. 使用configparser模块进行封装,构造配置文件处理器

    from configparser import ConfigParser class HandleConfig: ''' 定义一个配置文件处理类 ''' def __init__(self, fil ...

  7. dictionary vs Hashtables

    DictionaryDictionary is generic type Dictionary<TKey,TValue>Dictionary class is a strong type ...

  8. Java技巧——将前端的对象数组通过Json字符串传到后端并转换为对象集合

    Java技巧——将前端的对象数组通过Json字符串传到后端并转换为对象集合 摘要:本文主要记录了如何将将前端的对象数组通过Json字符串传到后端,并在后端将Json字符串转换为对象集合. 前端代码 前 ...

  9. 如何在CAD中批量打印图纸?这种方法你要知道

    CAD图纸都是使用CAD制图软件进行设计出来的,图纸的格式均为dwg格式的,不方便进行使用.就需要将图纸进行打印出来.多张CAD图纸如果一张一张进行打印速度就会非常的慢,那就可以使用CAD中的批量打印 ...

  10. 认识Metasploit框架

    Metasploit基础 认识Metaspliot框架 ​ Metaspliot(MSF)渗透测试框架,提供众多的接口.选项.变量.模块以供渗透工作人员使用它完成一系列的渗透攻击. 渗透攻击(Expl ...