思路:如果出现了一个强连通分量,那么走到这个点时一定会在强连通分量里的点全部走一遍,这样才能更大。所以我们首先用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. 配置了<mvc:resources> 导致以前的controller 无法访问。

    解决方案: <mvc:annotation-driven/>

  2. Scala underscore的用途

    _ 的用途 // import all import scala.io._ // import all, but hide Codec import scala.io.{Codec => _, ...

  3. web安全——防火墙

    简介 用于实现服务器(Linux)的访问控制的功能的. 分硬件和软件防火墙. 主要是控制访问的流入和服务器的流出. 通过黑名单和白名单的思想来实现更细粒度的控制,这个一般结合其他的应用来定义策略实现. ...

  4. Android从零开始——Android开发环境的安装

    Android开发环境的安装 1 IDE Android可以使用开发的IDE有Eclipse 或者 Android Studio.Android Studio还处于v 0.1.x版本,是early a ...

  5. 自己写的表格插件autotable

    自己写的表格插件autotable 作者:田想兵,个人网址:http://www.lovewebgames.com 这个表格插件所完成的功能是:ajax请求数据,然后动态绑定到指定表格下,格式化,分页 ...

  6. Javascript的封装

    js的封装分为以下几种模式: 工厂模式,代码如下: <!doctype html><html lang="en"><head><meta ...

  7. 案例分享:电信行业零售业务CRM架构

    最近跟一个客户讨论销售领域的移动化需求,谈到了他们的零售业务系统的整体框架,觉得很有分享的必要. 这次聊到的客户是电信行业的巨头,说的是他们的零售业务.电信公司么,卖出去的无非是设备和服务.大体的业务 ...

  8. R语言学习笔记:日期处理

    1.取出当前日期 Sys.Date() [1] "2014-10-29" date()  #注意:这种方法返回的是字符串类型 [1] "Wed Oct 29 20:36: ...

  9. 字符串匹配--Karp-Rabin算法

    主要特征 1.使用hash函数 2.预处理阶段时间复杂度O(m),常量空间 3.查找阶段时间复杂度O(mn) 4.期望运行时间:O(n+m) 本文地址:http://www.cnblogs.com/a ...

  10. IOS 应用跳转 (IOS9白名单)

    跳转到指定app的实现 IOS中应用的跳转是通过URL实现的,因此在实现应用跳转之前我们要设置一下对应的URL. 图一(寻找配置软件的URL) 图二(具体配置选项) 注意: 如果IOS版本为IOS9 ...