我们可以看出这个东西可以缩点成DAG,因为我们在所称的点里用特技的话,要么没用,要么削弱自己对点的收割能力与边的联通权,所以我们缩完点之后在图上枚举反向的变,因为我们只可能反向一条边,而且我们知道在这条边上走的方向,那么我们一定是在边终点回去,在边起点来,因为一来一回的这两条路径一定没有交叉所以我们找着两条路径的最大值,我们跑两边SPFA就好了,(一边正向,一边反向)。

注意在无向图Tarjan时要穷举,因为一个点可能走不完。

#include<cstdio>
#include<cstring>
#include<iostream>
#define MAXN 100005
using namespace std;
inline int read()
{
int sum=;
char ch=getchar();
while(ch<''||ch>'')ch=getchar();
while(ch>=''&&ch<='')
{
sum=(sum<<)+(sum<<)+ch-'';
ch=getchar();
}
return sum;
}
inline int Min(int x,int y)
{
return x<y?x:y;
}
inline int Max(int x,int y)
{
return x>y?x:y;
}
int dfn[MAXN],low[MAXN],when,stack[MAXN],top;
struct Tr
{
int to,next,w;
}C[MAXN],c[MAXN<<];
int Head[MAXN],T,head[MAXN],t;
bool in[MAXN];
inline void Add(int x,int y)
{
C[++T].to=y;
C[T].next=Head[x];
Head[x]=T;
}
int belong[MAXN],sum[MAXN],num;
int n,m;
void Tarjan(int x)
{
low[x]=dfn[x]=++when;
stack[++top]=x;
in[x]=;
for(int i=Head[x];i;i=C[i].next)
{
int y=C[i].to;
if(!dfn[y])
{
Tarjan(y);
low[x]=Min(low[x],low[y]);
}
else if(in[y])
low[x]=Min(low[x],dfn[y]);
}
if(dfn[x]==low[x])
{
int j;
num++;
do
{
j=stack[top--];
in[j]=;
belong[j]=num;
sum[num]++;
}while(j!=x);
}
}
inline void add(int x,int y,int z)
{
c[++t].to=y;
c[t].next=head[x];
head[x]=t;
c[t].w=z;
}
struct E
{
int x,y;
}e[MAXN];
int sz;
inline void buildnew()
{
for(int x=;x<=n;x++)
{
for(int i=Head[x];i;i=C[i].next)
{
int y=C[i].to;
if(belong[x]==belong[y])continue;
e[++sz].x=belong[x];
e[sz].y=belong[y];
add(belong[x],belong[y],);
add(belong[y],belong[x],);
}
}
}
int S,q[MAXN],tail,dis_to[MAXN],dis_from[MAXN];
void spfa1()
{
memset(dis_from,-,sizeof(dis_from));
dis_from[S]=;
q[]=S;
top=tail=;
in[S]=;
while(top<=tail)
{
int x=q[top++];
in[x]=;
for(int i=head[x];i;i=c[i].next)
if(c[i].w==)
{
if(dis_from[x]+sum[c[i].to]>dis_from[c[i].to])
{
dis_from[c[i].to]=dis_from[x]+sum[c[i].to];
if(!in[c[i].to])
in[c[i].to]=,q[++tail]=c[i].to;
}
}
}
}
void spfa2()
{
memset(dis_to,-,sizeof(dis_to));
q[]=S;
top=tail=;
dis_to[S]=sum[S];
in[S]=;
while(top<=tail)
{
int x=q[top++];
in[x]=;
for(int i=head[x];i;i=c[i].next)
if(c[i].w)
{
if(dis_to[x]+sum[c[i].to]>dis_to[c[i].to])
{
dis_to[c[i].to]=dis_to[x]+sum[c[i].to];
if(!in[c[i].to])
in[c[i].to]=,q[++tail]=c[i].to;
}
}
}
}
inline void Init()
{
n=read(),m=read();
for(int i=;i<=m;i++)
{
int x=read(),y=read();
Add(x,y);
}
for(int i=;i<=n;i++)
if(!dfn[i])
Tarjan(i);
buildnew();
S=belong[];
spfa1();
spfa2();
}
int ans;
inline void work()
{
ans=sum[S];
for(int i=;i<=sz;i++)
{
int x=e[i].y,y=e[i].x;
if(dis_to[x]==-||dis_from[y]==-)continue;
ans=Max(ans,dis_to[x]+dis_from[y]);
}
printf("%d",ans);
}
int main()
{
Init();
work();
return ;
}

【BZOJ3887】【Usaco2015 Jan】Grass Cownoisseur Tarjan+Spfa的更多相关文章

  1. BZOJ 3887: [Usaco2015 Jan]Grass Cownoisseur tarjan + spfa

    Code: #include <bits/stdc++.h> #define setIO(s) freopen(s".in","r",stdin) ...

  2. [Usaco2015 Jan]Grass Cownoisseur Tarjan缩点+SPFA

    考试的时候忘了缩点,人为dfs模拟缩点,没想到竟然跑了30分,RB爆发... 边是可以重复走的,所以在同一个强连通分量里,无论从那个点进入从哪个点出,所有的点一定能被一条路走到. 要使用缩点. 然后我 ...

  3. bzoj 3887: Grass Cownoisseur Tarjan+Topusort

    题目: 给一个有向图,然后选一条路径起点终点都为1的路径出来,有一次机会可以沿某条边逆方向走,问最多有多少个点可以被经过?(一个点在路径中无论出现多少正整数次对答案的贡献均为1) 题解: 首先考虑简单 ...

  4. BZOJ3887 [Usaco2015 Jan] Grass Cownoisseur 【tarjan】【DP】*

    BZOJ3887 [Usaco2015 Jan] Grass Cownoisseur Description In an effort to better manage the grazing pat ...

  5. 【洛谷P3119】[USACO15JAN]草鉴定Grass Cownoisseur

    草鉴定Grass Cownoisseur 题目链接 约翰有n块草场,编号1到n,这些草场由若干条单行道相连.奶牛贝西是美味牧草的鉴赏家,她想到达尽可能多的草场去品尝牧草. 贝西总是从1号草场出发,最后 ...

  6. 【题解】洛谷P3119 Grass Cownoisseur G

    题面:洛谷P3119 Grass Cownoisseur G 本人最近在熟悉Tarjan的题,刷了几道蓝题后,我飘了 趾高气扬地点开这道紫题,我一瞅: 哎呦!这不是分层图吗? 突然就更飘了~~~ 用时 ...

  7. 【Python】【容器 | 迭代对象 | 迭代器 | 生成器 | 生成器表达式 | 协程 | 期物 | 任务】

    Python 的 asyncio 类似于 C++ 的 Boost.Asio. 所谓「异步 IO」,就是你发起一个 IO 操作,却不用等它结束,你可以继续做其他事情,当它结束时,你会得到通知. Asyn ...

  8. 【Python】【面向对象】

    """# [[面向对象]]#[访问限制]#如果要让内部属性不被外部访问,可加双下划线,编程私有变量.只有内部可以访问,外部不能访问.class Student(objec ...

  9. 【Ruby】【基础】

    # [Ruby 块]=begin1 块由大量代码构成2 块中代码包含在{}内3 从与其相同名称的函数调用4 可以使用yield语句调用块=enddef test p '在test方法内' yield ...

随机推荐

  1. DJANGO2.0 关联表的必填 ON_DELETE

    DJANGO2.0 关联表的必填 ON_DELETE 参数的含义 - BUXIANGHEJIU 的博客 - CSDN 博客 版权声明:本文为博主原创文章,未经博主允许不得转载. https://blo ...

  2. flask(列表实现)

    在 index/views.py 中定义视图函数 在查询的时候,如果用户分类id传0,则不添加分类查询条件 @index_blu.route('/newslist') def get_news_lis ...

  3. PAT (Basic Level) Practice 1009 说反话

    给定一句英语,要求你编写程序,将句中所有单词的顺序颠倒输出. 输入格式: 测试输入包含一个测试用例,在一行内给出总长度不超过 80 的字符串.字符串由若干单词和若干空格组成,其中单词是由英文字母(大小 ...

  4. 记一次MD5妙用

    记一次MD5妙用 最近项目组中在做历史记录的改造工作,主持讨论了多次,但每次讨论完都觉的很完美了,但实际在写这部分逻辑的时候还是会发现一些问题出来,很难受,反反复复的暴露智商是硬伤,人艰不拆,暂先不扯 ...

  5. (数据科学学习手札33)基于Python的网络数据采集实战(1)

    一.简介 前面两篇文章我们围绕利用Python进行网络数据采集铺垫了很多内容,但光说不练是不行的,于是乎,本篇就将基于笔者最近的一项数据需求进行一次网络数据采集的实战: 二.网易财经股票数据爬虫实战 ...

  6. TRANSLATE(转换大/小写并替换字符)

    可以将字母 转换大/小 写或使用替 换规则. 要转换大/小 写,请使用 TRANSLATE 语句,用法 如下: 语法 TRANSLATE <c> TO UPPER CASE. TRANSL ...

  7. Oracle错误记录

    1 SQLPlus无法登陆oracle,PLSql可以登陆,报错ORA-12560 环境变量 右击计算机属性-->高级系统设置-->高级-->环境变量-->系统变量--> ...

  8. Hadoop学习(四) FileSystem Shell命令详解

    FileSystem Shell中大多数命令都和unix命令相同,只是两者之间的解释不同,如果你对unix命令有基本的了解,那么对于FileSystem Shell的命令,你将会感到很亲切. appe ...

  9. easyui 验证动态添加和删除问题

    $.extend($.fn.validatebox.methods, { remove: function(jq, newposition){ return jq.each(function(){ $ ...

  10. linux-clone-ip处理办法

    vim /etc/udev/rules.d/70-persistent-net.rules 步骤1:#将eth0相关的文件给删除 步骤2:#vi /etc/sysconfig/network-scri ...