【bzoj1179】 Apio2009—Atm

时间:2022-09-24 09:46:09

www.lydsy.com/JudgeOnline/problem.php?id=1179 (题目链接)

题意

  给出一张有向图,每个节点有点权。标记一些点,找出一条路径,可以重复经过一条边,使得总点权和最大。重复经过一个点不能重复算点权。

Solution

  今日考试题,Dijkstra不幸Gi烂。

  WARNING:Dijkstra处理最长路时会出现一些不好的情况,所以千万不要用!!

  既然可以重复经过一些边,那么一旦经过了某个环,我们一定可以把环上所有的点跑遍,所以做法就很显然了。先Tarjan缩点,所以整个图就变成有向无环图,跑DP或者SPFA最长路即可。

代码

// bzoj1179
#include<algorithm>
#include<iostream>
#include<cstdlib>
#include<cstring>
#include<cstdio>
#include<cmath>
#include<queue>
#define LL long long
#define inf 2147483640
#define Pi acos(-1.0)
#define free(a) freopen(a".in","r",stdin),freopen(a".out","w",stdout);
using namespace std; const int maxn=500010;
struct data {
int num,x;
friend bool operator < (const data &x,const data &y) {
return x.x<y.x;
}
};
struct edge {int to,next;}e[maxn<<1];
struct E {int u,v;}ee[maxn];
int dis[maxn],head[maxn],dfn[maxn],low[maxn],st[maxn],vis[maxn],pos[maxn],a[maxn],w[maxn],ll[maxn];
int n,m,top,sum,cnt,S,ind,p; void link(int u,int v) {
e[++cnt].to=v;e[cnt].next=head[u];head[u]=cnt;
}
void Tarjan(int x) {
dfn[x]=low[x]=++ind;
vis[x]=1;
st[++top]=x;
for (int i=head[x];i;i=e[i].next) {
if (!vis[e[i].to]) {
Tarjan(e[i].to);
low[x]=min(low[x],low[e[i].to]);
}
else if (!pos[e[i].to])
low[x]=min(low[x],dfn[e[i].to]);
}
if (dfn[x]==low[x]) {
sum++;
int j;
do {
j=st[top--];
pos[j]=sum;w[sum]+=a[j];
}while (st[top+1]!=x);
}
}
void Dijkstra() {
priority_queue<data> q;
for (int i=1;i<=sum;i++) dis[i]=-inf;
data y,x=(data){S,w[S]};
q.push(x);dis[S]=w[S];
while (q.size()) {
x=q.top();q.pop();
if (vis[x.num]) continue;
vis[x.num]=1;
for (int i=head[x.num];i;i=e[i].next)
if (dis[e[i].to]<dis[x.num]+w[e[i].to]) {
dis[e[i].to]=y.x=dis[x.num]+w[e[i].to];
y.num=e[i].to;
q.push(y);
}
}
}
void SPFA() {
queue<int> q;
for (int i=1;i<=sum;i++) dis[i]=-inf;
q.push(S);dis[S]=w[S];
while (q.size()) {
int x=q.front();q.pop();
vis[x]=0;
for (int i=head[x];i;i=e[i].next)
if (dis[e[i].to]<dis[x]+w[e[i].to]) {
dis[e[i].to]=dis[x]+w[e[i].to];
if (!vis[e[i].to]) q.push(e[i].to);
}
}
}
int main() {
scanf("%d%d",&n,&m);
for (int i=1;i<=m;i++) {
scanf("%d%d",&ee[i].u,&ee[i].v);
link(ee[i].u,ee[i].v);
}
for (int i=1;i<=n;i++) scanf("%d",&a[i]);
scanf("%d%d",&S,&p);
Tarjan(S);S=pos[S];
for (int x,i=1;i<=p;i++) {
scanf("%d",&x);
ll[pos[x]]=1;
}
for (int i=1;i<=n;i++) vis[i]=head[i]=0;
for (int i=1;i<=m;i++)
if (pos[ee[i].u]!=pos[ee[i].v]) link(pos[ee[i].u],pos[ee[i].v]);
//Dijkstra(); 万万不可
SPFA();
int ans=0;
for (int i=1;i<=sum;i++) if (ll[i]) ans=max(ans,dis[i]);
printf("%d",ans);
return 0;
}

  

【bzoj1179】 Apio2009—Atm的更多相关文章

  1. 【BZOJ1179】 &lbrack;Apio2009&rsqb;Atm tarjan缩点&plus;SPFA

    Description Input 第一行包含两个整数N.M.N表示路口的个数,M表示道路条数.接下来M行,每行两个整数,这两个整数都在1到N之间,第i+1行的两个整数表示第i条道路的起点和终点的路口 ...

  2. 【bzoj1179】&lbrack;Apio2009&rsqb;Atm Tarjan缩点&plus;Spfa最长路

    题目描述 输入 第一行包含两个整数N.M.N表示路口的个数,M表示道路条数.接下来M行,每行两个整数,这两个整数都在1到N之间,第i+1行的两个整数表示第i条道路的起点和终点的路口编号.接下来N行,每 ...

  3. 【bzoj1179】&lbrack;Apio2009&rsqb;Atm

    *题目描述: *输入: 第一行包含两个整数N.M.N表示路口的个数,M表示道路条数.接下来M行,每行两个整数,这两个整数都在1到N之间,第i+1行的两个整数表示第i条道路的起点和终点的路口编号.接下来 ...

  4. 【BZOJ1179】&lbrack;Apio2009&rsqb;Atm &lpar;tarjan&plus;SPFA&rpar;

    显而易见的tarjan+spfa...不解释了 ; type edgetype=record toward,next:longint; end; var edge1,edge2:..maxn] of ...

  5. 【Tarjan】&plus;【SPFA】APIO2009 Atm

    一.算法介绍 tarjan——求解有向图强连通分量.这个算法在本人的一篇blog中有介绍,这里就不赘述了.贴上介绍tarjan的的blog链接:http://www.cnblogs.com/Maki- ...

  6. 【BZOJ-1179】Atm Tarjan &plus; SPFA

    1179: [Apio2009]Atm Time Limit: 15 Sec  Memory Limit: 162 MBSubmit: 2407  Solved: 993[Submit][Status ...

  7. 【BZOJ 1179】&lbrack;Apio2009&rsqb;Atm

    [链接] 我是链接,点我呀:) [题意] 在这里输入题意 [题解] tarjan强连通缩点一下. 然后把缩点之后,每个点的钱的数累加起来. 然后从S出发 开始一边做bfs一遍做dp. 最后输出有酒吧的 ...

  8. 【题解】&lbrack;APIO2009&rsqb;会议中心

    [题解][P3626 APIO2009]会议中心 真的是一道好题!!!刷新了我对倍增浅显的认识. 此题若没有第二份输出一个字典序的方案,就是一道\(sort+\)贪心,但是第二问使得我们要用另外的办法 ...

  9. Tarjan缩点&plus;Spfa最长路【p3627】&lbrack;APIO2009&rsqb; 抢掠计划

    Description Siruseri 城中的道路都是单向的.不同的道路由路口连接.按照法律的规定, 在每个路口都设立了一个 Siruseri 银行的 ATM 取款机.令人奇怪的是,Siruseri ...

随机推荐

  1. Learning Spark 第四章——键值对处理

    本章主要介绍Spark如何处理键值对.K-V RDDs通常用于聚集操作,使用相同的key聚集或者对不同的RDD进行聚集.部分情况下,需要将spark中的数据记录转换为键值对然后进行聚集处理.我们也会对 ...

  2. Android Service 文档

    应用场景: 1  用于将后台逻辑(Service中)和UI逻辑(Activity中)进行解耦,实现Service功能的复用,为其他程序提供功能. 2  后台功能,由于Activity在进入后台时(On ...

  3. 【fedora】设置fedora系统

    1.安装自动选择最快源的插件fastestmirror: #sudo yum -y install axel yum-plugin-fastestmirror && sudo yum ...

  4. Jquer Ajax xmlhttp请求成功了,为什么一直在error函数里面

    转载自http://www.cnblogs.com/sky_Great/archive/2013/01/18/2866861.html 并进行整理: 今天遇到了一个极其奇怪的问题,用各种工具检查都能看 ...

  5. Laravel-数据库操作笔记

    (慕课网_轻松学会Laravel-基础篇_天秤vs永恒老师) 一.直接使用sql语句 1.路由 2.StudentController.php 二.查询构造器 简介:Laravel查询构造器(quer ...

  6. 构造activeMQ

    一.添加下列库 而配置的路径 ws2_32.lib;Mswsock.lib;cppunit.lib;libapr-1.lib;libapriconv-1.lib;libaprutil-1.lib;li ...

  7. C&num; 关闭子线程的方法

    将子线程设定为IsBackGroud = true,程序关闭则自动死亡. 暴力手段:System.Environment.Exit(0).关闭时直接x掉所有线程. 子线程自行结束:子线程中自己判断.可 ...

  8. Jquery的ajax在IE提交数据乱码解决方法

    原文地址:http://fatkun.com/2010/12/jquery-ajax.html 乱码是因为编码不同而造成的.在ajax post 或 get时都有可能出现乱码. 为了避免乱码,可以做到 ...

  9. 【Java并发编程】1、ConcurrentHashMap原理分析

    集合是编程中最常用的数据结构.而谈到并发,几乎总是离不开集合这类高级数据结构的支持.比如两个线程需要同时访问一个中间临界区(Queue),比如常会用缓存作为外部文件的副本(HashMap).这篇文章主 ...

  10. English trip -- VC&lpar;情景课&rpar;3 D Reading

    xu言: 感觉睡眠尽量还是要保证7+小时,才能让自己的脑袋更清醒一些... Read 阅读 My Family My name is Gloria. This is my family . This ...