题目传送门

Description

Siruseri 城中的道路都是单向的。不同的道路由路口连接。按照法律的规定, 在每个路口都设立了一个 Siruser
i 银行的 ATM 取款机。令人奇怪的是,Siruseri 的酒吧也都设在路口,虽然并不是每个路口都设有酒吧。Bandit
ji 计划实施 Siruseri 有史以来最惊天动地的 ATM 抢劫。他将从市中心 出发,沿着单向道路行驶,抢劫所有他
途径的 ATM 机,最终他将在一个酒吧庆 祝他的胜利。使用高超的黑客技术,他获知了每个 ATM 机中可以掠取的
现金数额。他希 望你帮助他计算从市中心出发最后到达某个酒吧时最多能抢劫的现金总数。他可 以经过同一路口
或道路任意多次。但只要他抢劫过某个 ATM 机后,该 ATM 机 里面就不会再有钱了。 例如,假设该城中有 6 个
路口,道路的连接情况如下图所示:
市中心在路口 1,由一个入口符号→来标识,那些有酒吧的路口用双圈来表示。每个 ATM 机中可取的钱数标在了
路口的上方。在这个例子中,Banditji 能抢 劫的现金总数为 47,实施的抢劫路线是:1-2-4-1-2-3-5。
输出一个整数,表示Banditji从市中心开始到某个酒吧结束所能抢劫的最多的现金总数。
 

Sol

感觉这题思路还是很明了的...先进行一遍tarjan求出图中所有的强连通分量,将他们缩点,然后在这个DAG中跑一遍spfa求最长路。

坑点:好像不能用dijkstra+heap求最长路&&主程序中调用tarjan不能仅一次。

 #include<cstdio>
#include<algorithm>
#include<stack>
#include<queue>
#include<cstring>
#define maxn 500090 using namespace std;
typedef long long ll; int n,m,tot,sp,P,dfs_clock,scc_cnt;
int head[maxn],Head[maxn],val[maxn],dfn[maxn],low[maxn],scc[maxn],pub[maxn];
bool vis[maxn];
ll ans,scc_val[maxn],dis[maxn];
struct node{
int to,next;
}edge[maxn],Edge[maxn];
stack<int>st; void add(int x,int y)
{
edge[++tot].to=y;
edge[tot].next=head[x];
head[x]=tot;
} void ADD(int x,int y)
{
Edge[++tot].to=y;
Edge[tot].next=Head[x];
Head[x]=tot;
} void tarjan(int u)
{
dfn[u]=low[u]=++dfs_clock;
st.push(u);
for(int i=head[u];i;i=edge[i].next)
{
int v=edge[i].to;
if(!dfn[v])
{
tarjan(v);
low[u]=min(low[u],low[v]);
}
else if(!scc[v]) low[u]=min(low[u],dfn[v]);
}
if(low[u]==dfn[u])
{
scc_cnt++;
while()
{
int x=st.top();st.pop();
scc[x]=scc_cnt;
scc_val[scc_cnt]+=val[x];
if(x==u) break;
}
}
} void dijkstra(int s)
{
priority_queue<pair<ll,int> >q;
for(int i=;i<=scc_cnt;i++) dis[i]=-;
q.push(make_pair(,s));dis[s]=scc_val[s];
while(!q.empty())
{
int u=q.top().second;q.pop();
if(vis[u]) continue;
vis[u]=;
for(int i=Head[u];i;i=Edge[i].next)
{
int v=Edge[i].to;
if(dis[v]<dis[u]+scc_val[v])
{
dis[v]=dis[u]+scc_val[v];
q.push(make_pair(dis[v],v));
}
}
}
} int main()
{
scanf("%d%d",&n,&m);
for(int i=;i<=m;i++)
{
int x=,y=;
scanf("%d%d",&x,&y);
add(x,y);
}
for(int i=;i<=n;i++) scanf("%d",&val[i]);
for(int i=;i<=n;i++)
if(!dfn[i]) tarjan(i);
tot=;
for(int x=;x<=n;x++)
for(int i=head[x];i;i=edge[i].next)
{
int y=edge[i].to;
if(scc[x]!=scc[y])
ADD(scc[x],scc[y]);
}
scanf("%d%d",&sp,&P);
for(int i=;i<=P;i++) scanf("%d",&pub[i]);
dijkstra(scc[sp]);
for(int i=;i<=P;i++)
ans=max(ans,dis[scc[pub[i]]]);
printf("%lld\n",ans);
return ;
}

最新文章

  1. 每日学习笔记:js中可以直接用id名调用的问题?
  2. hibernate4中使用Session doWork()方法进行jdbc操作(代码)
  3. slf4j和log4j配置
  4. Android IOS WebRTC 音视频开发总结(五二)-- 亲,咱一起采访webrtc大会的各路专家
  5. JRPC 轻量级RPC框架
  6. 使用font-size:0去掉inline-block元素之间的空隙
  7. 软硬件协同编程 - C#玩转CPU高速缓存(附示例)
  8. ldap集成bitbucket
  9. grid - 网格项目对齐方式(Box Alignment)
  10. java中异常处理
  11. 一个数学不好的菜鸡的快速沃尔什变换(FWT)学习笔记
  12. java json-lib配置
  13. Python3入门(六)——函数式编程
  14. Linux 物理内存 buffer cache
  15. Codeforces 148D 一袋老鼠 Bag of mice | 概率DP 水题
  16. [iOS]使用Windows Azure來做iOS的推播通知 (转帖)
  17. Window窗口布局 --- DecorView浅析
  18. 关于latex的画图
  19. 使用PowerDesigner建立数据库模型【转】
  20. STM32 中断应用概览

热门文章

  1. uva 1567 - A simple stone game(K倍动态减法游戏)
  2. hdu 3746 Cyclic Nacklace (KMP求最小循环节)
  3. 1507: [NOI2003]Editor
  4. 安装sbt
  5. pyenv 安装本地版本
  6. 更改scroll样式
  7. ADB运行框架原理解析【转】
  8. Spring3 Schedule Task之注解实现 (两次起动Schedule Task 的解决方案)
  9. SideBar---fixed定位
  10. MFC之document与view实践总结