思路:如果出现了一个强连通分量,那么走到这个点时一定会在强连通分量里的点全部走一遍,这样才能更大。所以我们首先用Tarjan跑一遍求出所有强连通分量,然后将强连通分量缩成点(用到栈)然后就变成了一个DAG(有向无环图),然后跑一遍DFS,不断加上遍历点的权值,如果到了网吧,则更新一遍答案,因为可以出去了。

求强连通分量时,如果low[u] == dfn[u],说明形成了一个新的强连通分量,且根为u。具体求强连通分量见:http://www.cnblogs.com/whatbeg/p/3776422.html

代码:

#include <iostream>
#include <cstdio>
#include <cstring>
#include <cmath>
#include <algorithm>
#include <stack>
using namespace std;
#define N 100007 struct Edge
{
int v,next;
}G[*N],G2[*N]; int first[*N],first2[*N],low[N],dfn[N];
int instk[N],bel[N],coin[N],iswb[N],wb[N],coin2[N];
int tot,tot2,n,m,Time,cnt,P,K,res;
stack<int> stk; void addedge(Edge *G,int& tot,int *first,int u,int v)
{
G[tot].v = v;
G[tot].next = first[u];
first[u] = tot++;
} void Tarjan(int u)
{
low[u] = dfn[u] = ++Time;
stk.push(u);
instk[u] = ;
for(int i=first[u];i!=-;i=G[i].next)
{
int v = G[i].v;
if(!dfn[v]) //树边
{
Tarjan(v);
low[u] = min(low[u],low[v]);
}
else if(instk[v]) //回边
low[u] = min(low[u],dfn[v]);
}
if(low[u] == dfn[u])
{
cnt++;
int v;
do
{
v = stk.top();
stk.pop();
if(iswb[v])
wb[cnt] = ;
instk[v] = ;
coin2[cnt] += coin[v];
bel[v] = cnt;
if(v == P)
P = cnt;
}while(u != v);
}
} void dfs(int u,int sum)
{
sum += coin2[u];
if(wb[u])
res = max(res,sum);
for(int i=first2[u];i!=-;i=G2[i].next)
{
int v = G2[i].v;
dfs(v,sum);
}
} int main()
{
int i,j,u,v;
while(scanf("%d%d",&n,&m)!=EOF)
{
memset(first,-,sizeof(first));
memset(first2,-,sizeof(first2));
memset(G,,sizeof(G));
memset(G2,,sizeof(G2));
memset(iswb,,sizeof(iswb));
memset(wb,,sizeof(wb));
memset(instk,,sizeof(instk));
memset(bel,-,sizeof(bel));
memset(coin2,,sizeof(coin2));
memset(low,,sizeof(low));
memset(dfn,,sizeof(dfn));
tot = tot2 = ;
Time = cnt = ;
while(!stk.empty())
stk.pop();
for(i=;i<m;i++)
{
scanf("%d%d",&u,&v);
addedge(G,tot,first,u,v);
}
for(i=;i<=n;i++)
scanf("%d",&coin[i]);
scanf("%d",&P);
scanf("%d",&K);
for(i=;i<K;i++)
{
scanf("%d",&v);
iswb[v] = ;
}
for(v=;v<=n;v++) //Tarjan求强连通分量
{
if(!dfn[v])
Tarjan(v);
}
for(i=;i<=n;i++) //重建为一个DAG
{
for(j=first[i];j!=-;j=G[j].next)
{
v = bel[G[j].v];
u = bel[i];
if(u != v) //如果相连点不是一个连通分量
addedge(G2,tot2,first2,u,v); //建桥
}
}
res = -;
dfs(P,);
printf("%d\n",res);
}
return ;
}

UESTC 901 方老师抢银行 --Tarjan求强连通分量的更多相关文章

  1. UESTC 898 方老师和缘分 --二分图匹配+强连通分量

    这题原来以为是某种匹配问题,后来好像说是强连通的问题. 做法:建图,每个方老师和它想要的缘分之间连一条有向边,然后,在给出的初始匹配中反向建边,即如果第i个方老师现在找到的是缘分u,则建边u-> ...

  2. tarjan求强连通分量+缩点+割点以及一些证明

    “tarjan陪伴强联通分量 生成树完成后思路才闪光 欧拉跑过的七桥古塘 让你 心驰神往”----<膜你抄>   自从听完这首歌,我就对tarjan开始心驰神往了,不过由于之前水平不足,一 ...

  3. Tarjan求强连通分量,缩点,割点

    Tarjan算法是由美国著名计算机专家发明的,其主要特点就是可以求强连通分量和缩点·割点. 而强联通分量便是在一个图中如果有一个子图,且这个子图中所有的点都可以相互到达,这个子图便是一个强连通分量,并 ...

  4. tarjan求强连通分量+缩点+割点/割桥(点双/边双)以及一些证明

    “tarjan陪伴强联通分量 生成树完成后思路才闪光 欧拉跑过的七桥古塘 让你 心驰神往”----<膜你抄>   自从听完这首歌,我就对tarjan开始心驰神往了,不过由于之前水平不足,一 ...

  5. HDU 1827 Summer Holiday(tarjan求强连通分量+缩点构成新图+统计入度+一点贪心思)经典缩点入门题

    Summer Holiday Time Limit: 10000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)T ...

  6. CCF 高速公路 tarjan求强连通分量

    问题描述 某国有n个城市,为了使得城市间的交通更便利,该国国王打算在城市之间修一些高速公路,由于经费限制,国王打算第一阶段先在部分城市之间修一些单向的高速公路. 现在,大臣们帮国王拟了一个修高速公路的 ...

  7. UVALive 4262——Trip Planning——————【Tarjan 求强连通分量个数】

    Road Networks Time Limit:3000MS     Memory Limit:0KB     64bit IO Format:%lld & %llu Submit Stat ...

  8. tarjan求强连通分量(模板)

    https://www.luogu.org/problem/P2341 #include<cstdio> #include<cstring> #include<algor ...

  9. Tarjan求强连通分量、求桥和割点模板

    Tarjan 求强连通分量模板.参考博客 #include<stdio.h> #include<stack> #include<algorithm> using n ...

随机推荐

  1. 安装xampp无法设置默认时间的坑

    xampp无法设置默认时间,修改了时间还是无效 [Date] ; Defines the default timezone used by the date functions ; http://ph ...

  2. Linux下安装配置Nexus

    一.安装和运行nexus 1.下载nexus:http://www.sonatype.org/nexus/go 可选择tgz和zip格式,以及war,选择tgz或zip时不同版本可能在启动时存在一定问 ...

  3. Angularjs,WebAPI 搭建一个简易权限管理系统 —— 基本功能演示(二)

    目录 前言 Angularjs名词与概念 Angularjs 基本功能演示 系统业务与实现 WebAPI项目主体结构 Angularjs 前端主体结构 基本功能演示(二) 非常抱歉这个月实在太忙,一直 ...

  4. DirectX 9 SDK安装后在vs2010里编译BaseClasses出错问题解决方法

    打开你的dx的sdk安装目录,例如: D:/DX90SDK/Samples/C++/DirectShow/ 这里就有一个叫baseclasses的工程,为安全起见,请先备份此工程. 1,双击basec ...

  5. 备份一张iPhone拍照写入exif中的orientation图片

  6. A除以B问题

    描述:本题要求计算A/B,其中A是不超过1000位的正整数,B是1位正整数.你需要输出商数Q和余数R,使得A = B * Q + R成立. 输入:输入在1行中依次给出A和B,中间以1空格分隔. 输出: ...

  7. ASP.NET中UEditor使用

    ASP.NET中UEditor使用 0.ueditor简介 UEditor是由百度WEB前端研发部开发的所见即所得的开源富文本编辑器,具有轻量.可定制.用户体验优秀等特点.开源基于BSD协议,所有源代 ...

  8. c# Json Dictionary序列化和反序列化

    说明:Dictionary对象本身不支持序列化和反序列化,需要定义一个继承自Dictionary, IXmlSerializable类的自定义类来实现该功能.感觉完全可以把这样的类封装到C#库中,很具 ...

  9. 错误:升级为xcode8之后无法上网的解决方法

    主要是在info.list中增加以下的节点,因为XCode开始所有的http都转为https来联网了. 添加类型为Dictionary的:NSAppTransportSecurity 再添加节点为:N ...

  10. iOS开发~UI布局(三)深入理解autolayout

    一.概要 通过对iOS8界面布局的学习和总结,发现autolayout才是主角,autolayout是iOS6引入的新特性,当时还粗浅的学习了下,可是没有真正应用到项目中.随着iOS设备尺寸逐渐碎片化 ...