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

题解:

  一道比较综合的图论题
  直接讲正解:
  如果这个图G中存在某个强连通分量,那么这个强连通分量中的所有ATM即可视为都被抢到,所有的酒吧都可视为重点,并且也可以从这个强连通分量的任何结点出发继续向外扩展
  所以先做一遍Tarjan,找出强连通分量,然后重新构图,把每个强连通分量缩成一个点,此点的权值即为原先强连通分量里所有点权之和,判断此点中有没有酒吧,再将原先所有连接强连通分量的边连接在这个点
  最后做SPFA,找出权值最大的路径
  这道题时间限制15s,空间162MB,所以一般不会TLE或MLE
 #include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
#define MAXN 500010
#define MAXM 500010
int n,m,time,cnt,head1[MAXN],DFN[MAXN],Low[MAXN],stack[MAXN],top,a1[MAXN],belong[MAXN];
bool vis[MAXN],bar1[MAXN];
struct node1
{
int v,next;
}edge1[MAXM];
//以上变量基本是在进行tarjan(及之前)使用
int heads[MAXN],mm,a2[MAXN],s,p,d[MAXN],q[MAXN],head,tail,ans;
bool viss[MAXN];
struct node2
{
int v,next;
}edge2[MAXM];
//以上变量是在进行SPFA时使用
//a存放点权,bar记录是否有酒吧
bool bar2[MAXN];
void add(int x,int y)
{
edge1[++cnt].next=head1[x];
head1[x]=cnt;
edge1[cnt].v=y;
}
void buildmap(int k)//重新建图、连边
{
for(int i=;i<=n;i++)
{
if(belong[i]==k)
{
for(int j=head1[i];j;j=edge1[j].next)
{
if(belong[edge1[j].v]==k)continue;
edge2[++m].next=heads[k];
heads[k]=m;
edge2[m].v=belong[edge1[j].v];
}
}
}
}
void tarjan(int u)
{
DFN[u]=Low[u]=++time;
vis[u]=true;
stack[++top]=u;
for(int i=head1[u];i;i=edge1[i].next)
{
int v=edge1[i].v;
if(!DFN[v])
{
tarjan(v);
Low[u]=min(Low[u],Low[v]);
}
else if(vis[v])Low[u]=min(Low[u],DFN[v]);
}
if(DFN[u]==Low[u])
{
int i;
cnt++;
do
{
i=stack[top--];
vis[i]=false;
belong[i]=cnt;
a2[cnt]+=a1[i];
if(bar1[i])bar2[cnt]=true;//先更新点权和是否有酒吧
}while(u!=i);
}
}
void SPFA()
{
head=;tail=;
q[]=s;
viss[s]=;
while(head<tail)
{
for(int i=heads[q[head]];i!=;i=edge2[i].next)
{
if(d[q[head]]+a2[edge2[i].v]>d[edge2[i].v])//注意,这里不是边权,是点权
{
d[edge2[i].v]=d[q[head]]+a2[edge2[i].v];
if(!viss[edge2[i].v])
{
q[tail++]=edge2[i].v;
viss[edge2[i].v]=true;
}
}
}
viss[q[head]]=false;
head++;
}
}
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",&a1[i]);
}
scanf("%d%d",&s,&p);
for(int i=;i<=p;i++)
{
int x;
scanf("%d",&x);
bar1[x]=true;
}
cnt=;
m=;
for(int i=;i<=n;i++)
if(!DFN[i])tarjan(i);
for(int i=;i<=cnt;i++)
buildmap(i);
s=belong[s];
for(int i=;i<=cnt;i++)
{
d[i]=a2[i];
}
SPFA();
for(int i=;i<=cnt;i++)
{
if(bar2[i])ans=max(ans,d[i]);
}
printf("%d",ans);
return ;
}

bzoj 1179 Atm的更多相关文章

  1. BZOJ 1179 Atm 题解

    BZOJ 1179 Atm 题解 SPFA Algorithm Tarjan Algorithm Description Input 第一行包含两个整数N.M.N表示路口的个数,M表示道路条数.接下来 ...

  2. BZOJ 1179 Atm(强连通分量缩点+DP)

    题目说可以通过一条边多次,且点权是非负的,所以如果走到图中的一个强连通分量,那么一定可以拿完这个强连通分量上的money. 所以缩点已经很明显了.缩完点之后图就是一个DAG,对于DAG可以用DP来求出 ...

  3. bzoj 1179 [APIO 2009]Atm(APIO水题) - Tarjan - spfa

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

  4. BZOJ 1179: [Apio2009]Atm( tarjan + 最短路 )

    对于一个强连通分量, 一定是整个走或者不走, 所以tarjan缩点然后跑dijkstra. ------------------------------------------------------ ...

  5. bzoj 1179[Apio2009]Atm (tarjan+spfa)

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

  6. BZOJ 1179 [Apio2009]Atm(强连通分量)

    [题目链接] http://www.lydsy.com/JudgeOnline/problem.php?id=1179 [题目大意] 给出一张有向带环点权图,给出一些终点,在路径中同一个点的点权只能累 ...

  7. bzoj 1179: [Apio2009]Atm

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

  8. bzoj 1179 [Apio2009]Atm 缩点+最短路

    [Apio2009]Atm Time Limit: 15 Sec  Memory Limit: 162 MBSubmit: 4290  Solved: 1893[Submit][Status][Dis ...

  9. BZOJ 1179 抢掠计划atm (缩点+有向无环图DP)

    手动博客搬家: 本文发表于20170716 10:58:18, 原地址https://blog.csdn.net/suncongbo/article/details/81061601 https:// ...

随机推荐

  1. Codeforces Round #522 Div. 1 没打记

    开场被A劝退,写了得有50min于是不敢交了.unrated了喜闻乐见. A:瞎猜都能猜到如果要走到那条直线上,进入直线的点横坐标或纵坐标与起点相同,离开直线的点横坐标或纵坐标与终点相同,证明脑补一下 ...

  2. PKUWC2019 酱油记

    目录 PKUWC2019 酱油记 day0 Day1 Day2 Day3 Day4 PKUWC2019 酱油记 day0 早上从镇中出发到栎社机场,然后才了解到原来充电宝电脑是必须随身(原以为必须托运 ...

  3. React的setState执行机制

    1. setState基本特点 1. setState是同步执行的 setState是同步执行的,但是state并不一定会同步更新 2. setState在React生命周期和合成事件中批量覆盖执行 ...

  4. bzoj1024: [SCOI2009]生日快乐(DFS)

    dfs(x,y,n)表示长为x,宽为y,切n块 每次砍的一定是x/n的倍数或者y/n的倍数 #include<bits/stdc++.h> using namespace std; con ...

  5. 学习web安全之--初识安全

    随笔:随着互联网行业的飞速发展,互联网行业可谓日新月异,然而在繁华的背后,大多的互联网公司对于网络安全还是处于无重视,不作为的阶段,而作为一个程序员,如果也对信息安全视而不见的话,那将是这个公司的噩梦 ...

  6. 关于web.xml中的<welcome-file-list>中的默认首页资料

    关于web.xml中的<welcome-file-list>中的默认首页文件 先看我的配置文件: <welcome-file-list> <welcome-file> ...

  7. MyEclipse安装FreeMarker插件

      MyEclipce8.6中安装FreeMarker插件,这绝对是最简单的方法.   步骤如下:   (一)打开http://sourceforge.net/projects/freemarker- ...

  8. G - YYS FZU - 2278 数学期望 (大数)

    Yinyangshi is a famous RPG game on mobile phones. Kim enjoys collecting cards in this game. Suppose ...

  9. How to configue session timeout in Hive

    This article explains how to configure the following settings in Hive:hive.server2.session.check.int ...

  10. [技巧篇]03.关于MyBatis的简单批量处理