【Bzoj1179】[Apio2009]抢掠计划atm
2017-11-08 14:56
211 查看
时间限制:1S / 空间限制:256MB
tarjan缩点重构图,然后在重构图上跑最长(短)路,最后的答案就是max(dis[有酒吧的点])
注意:
1.还是要注意,重构图和原图不能搞混了……
2.如果跑最长路的话,dis不要初始化为0,可能出现起点周围的点权都是0,直接导致从起点搜索一遍,没有点入队的情况
【在线测试提交传送门】
【问题描述】
【输入格式】
第一行包含两个整数N、M。N表示路口的个数,M表示道路条数。 接下来M行,每行两个整数,这两个整数都在1到N之间,第i+1行的两个整数表示第i条道路的起点和终点的路口编号。 接下来N行,每行一个整数,按顺序表示每个路口处的ATM机中的钱数。 接下来一行包含两个整数S、P,S表示市中心的编号,也就是出发的路口。P表示酒吧数目。 接下来的一行中有P个整数,表示P个有酒吧的路口的编号
【输出格式】
输出一个整数,表示Banditji从市中心开始到某个酒吧结束所能抢劫的最多的现金总数。
【输入样例1】
6 7 1 2 2 3 3 5 2 4 4 1 2 6 6 5 10 12 8 16 1 5 1 4 4 3 5 6
【输出样例1】
47
【说明】
50%的输入保证N, M≤3000。 所有的输入保证N, M≤500000。每个ATM机中可取的钱数为一个非负整数且不超过4000。 输入数据保证你可以从市中心沿着Siruseri的单向的道路到达其中的至少一个酒吧。
【题目来源】
Bzoj1179 Apio2009【解题思路】
题目中是一个带点权的有向图,如果这是一个没有环的图那么问题就很简单,拓扑或者直接求最长(短)路径什么的信手拈来,但是它有环,这就要求我们对图进行重构,把它搞成一个有向无环图,然后求得极值路径就可以了tarjan缩点重构图,然后在重构图上跑最长(短)路,最后的答案就是max(dis[有酒吧的点])
注意:
1.还是要注意,重构图和原图不能搞混了……
2.如果跑最长路的话,dis不要初始化为0,可能出现起点周围的点权都是0,直接导致从起点搜索一遍,没有点入队的情况
【参考代码】
#include<bits/stdc++.h> using namespace std; #define M 500005 int in() { int t=0;char ch=getchar(); while (!isdigit(ch)) ch=getchar(); while (isdigit(ch)) t=(t<<1)+(t<<3)+ch-48,ch=getchar(); return t; } int n=in(),m=in(),s,p,tot,cnt; struct edge{int u,v,next;}e[M],E[M]; int first[M],c[M],dfn[M],low[M],belong[M],First[M],C[M],dis[M]; bool is_end[M],vis[M]; stack<int>S; queue<int>Q; void add(int y,int x){e[++tot]=(edge){x,y,first[x]};first[x]=tot;} void Add(int x,int y){E[++tot]=(edge){x,y,First[x]};First[x]=tot;} void dfs(int x) { dfn[x]=low[x]=++cnt; S.push(x); vis[x]=1; for (int i=first[x];i;i=e[i].next) if (!dfn[e[i].v]) dfs(e[i].v), low[x]=min(low[x],low[e[i].v]); else if (vis[e[i].v]) low[x]=min(low[x],dfn[e[i].v]); if (dfn[x]==low[x]) { C[x]=0; for (int y=-1;y!=x;y=S.top(),S.pop()) belong[S.top()]=x, C[x]+=c[S.top()], vis[S.top()]=0; } } main() { for (int i=1;i<=m;i++) add(in(),in()); for (int i=1;i<=n;i++) c[i]=in(); s=in();p=in(); for (int i=1;i<=p;i++) is_end[in()]=1; tot=0; for (int i=1;i<=n;i++) if (!dfn[i]) dfs(i); for (int i=1;i<=n;i++) for (int j=first[i];j;j=e[j].next) if (belong[i]!=belong[e[j].v]) Add(belong[i],belong[e[j].v]); memset(dis,63,sizeof(dis)); Q.push(belong[s]);vis[belong[s]]=1; dis[belong[s]]=-C[belong[s]]; while (!Q.empty()) { int x=Q.front(); Q.pop(); vis[x]=0; for (int i=First[x];i;i=E[i].next) if (dis[x]-C[E[i].v]<dis[E[i].v]) { dis[E[i].v]=dis[x]-C[E[i].v]; if (!vis[E[i].v]) Q.push(E[i].v),vis[E[i].v]=1; } } int ans=0; for (int i=1;i<=n;i++) if (is_end[i]) ans=min(ans,dis[belong[i]]); printf("%d",-ans); }
相关文章推荐
- 【bzoj1179】[Apio2009]抢掠计划atm 强连通分量缩点+spfa
- BZOJ1179_APIO2009_抢掠计划_C++
- 【APIO2009】BZOJ1179 BSOJ2468 CODEVS1611 抢掠计划
- [强联通+SPFA] bzoj1179: [Apio2009]Atm
- bzoj 1179: [Apio2009]Atm(Trajan+SPFA)
- BZOJ1179 [Apio2009]Atm 【tarjan缩点】
- 【BZOJ1179】[Apio2009]Atm【SCC】【最长路】
- BZOJ 1179 APIO2009 ATM Tarjan+堆优化SPFA
- bzoj1179 [Apio2009]Atm[tarjan缩点]
- BZOJ1179 [Apio2009]Atm
- 【BZOJ】1179: [Apio2009]Atm(tarjan+spfa)
- 【bzoj1179】[Apio2009]Atm Tarjan缩点+Spfa最长路
- bzoj1179 [Apio2009]Atm
- bzoj1179: [Apio2009]Atm
- bzoj1179 [Apio2009]Atm
- bzoj 1179 [APIO 2009]Atm(APIO水题) - Tarjan - spfa
- bzoj 1179 [Apio2009]Atm tarjan强联通缩点+SPFA
- BZOJ 1179: [Apio2009]Atm(tarjan缩点+spfa)
- BZOJ 1179: [Apio2009]Atm Tarjan强连通分量缩点,SPFA,DP
- 【强连通分量+spfa】Bzoj1179 Apio2009 Atm