「P3627 [APIO2009] 抢掠计划(ATM)」题解
1.「P3627 [APIO2009] 抢掠计划(ATM)」题解
2.「P3225 [HNOI2012] 矿场搭建」题解3.「P3214 [HNOI2011] 卡农」题解4.「旅游景点 Tourist Attractions」题解5.「ARC_172_A_Chocolate」题解6.「P1967 [NOIP 2013 提高组] 货车运输」题解7.「佳佳的 Fibonacci」题解8.「Fibonacci 前 n 项和」题解9.「P10668 BZOJ2720 [Violet 5] 列队春游」题解10.「P7394 「TOCO Round 1」History」题解11.「ABC375」题解12.「P6054 [RC-02] 开门大吉」题解13.「最小割树」学习笔记 & 「P4897 【模板】最小割树(Gomory-Hu Tree)」 题解- 题目描述:
城中的道路都是单向的。不同的道路由路口连接。按照法律的规定, 在每个路口都设立了一个 银行的 取款机。令人奇怪的是, 的酒吧也都设在路口,虽然并不是每个路口都设有酒吧。 计划实施 有史以来最惊天动地的 抢劫。他将从市中心 出发,沿着单向道路行驶,抢劫所有他 途径的 机,最终他将在一个酒吧庆 祝他的胜利。使用高超的黑客技术,他获知了每个 机中可以掠取的 现金数额。他希望你帮助他计算从市中心出发最后到达某个酒吧时最多能抢劫的现金总数。他可 以经过同一路口 或道路任意多次。但只要他抢劫过某个 机后,该 机 里面就不会再有钱了。 例如,假设该城中有 个 路口,道路的连接情况如下图所示
市中心在路口 ,由一个入口符号→来标识,那些有酒吧的路口用双圈来表示。每个 机中可取的钱数标在了路口的上方。在这个例子中, 能抢 劫的现金总数为 ,实施的抢劫路线是: 。 - 输入格式: 第一行包含两个整数
、 。 表示路口的个数, 表示道路条数。 接下来 行,每行两个整数,这两个整数都在 到 之间, 第 行的两个整数表示第 条道路的起点和终点的路口编号。 接下来 行,每行一个整数,按顺序表示每个路口处的 机中的钱数。 接下来一行包含两个整数 、 , 表示市中心的编号,也就是出发的路口。 表示酒吧数目。 接下来的一行中有 个整数,表示 个有酒吧的路口的编号 。每个 机中可取的钱数为一个非负整数且不超过 。 输入数据保证你可以从市中心沿着 的单向的道路到达其中的至少一个酒吧。 - 输出格式:输出一个整数,表示
从市中心开始到某个酒吧结束所能抢劫的最多的现金总数。
可以想到
这就比较该死,直接
输入的时候存了一下这个from和to,为的是缩完点后再次建图时的判断,如果该条路上起点和终点在一个连通块里,自然就不需要把他们俩再连起来了
for(int i=1;i<=m;i++) if(color[from[i]]!=color[to[i]]) e[color[from[i]]].push_back(color[to[i]]);
于是谈到了再次建图,用 &tarjan$ 缩完点后,建一遍缩完点的图,再跑
我这里没有建两个图,缩完点后之前的图就没用了,吧之前的图初始化掉再建一遍新的图就好了
memset(e,0,sizeof(e)); for(int i=1;i<=m;i++) if(color[from[i]]!=color[to[i]]) e[color[from[i]]].push_back(color[to[i]]);
观察输入可以发现他讲出发点和结束点给了,出发点就是
然后发现这个玩意在跑
像这样
for(i=1;i<=pos;++i)ls=read(),club[ls]=1;
if(club[z])win[tot]=1;
for(i=1;i<=tot;++i)if(win[i])ansss=max(ansss,dis[i]);
但是如果把他在后面输入,就可以只
for(int i=1;i<=p;i++) read(bar),ans=max(ans,d[color[bar]]);
全部代码
#include<bits/stdc++.h> #define int long long #define endl "\n" using namespace std; const int N=500001; template<typename Tp> inline void read(Tp&x) { x=0;register bool f=1; register char c=getchar(); for(;c<'0'||c>'9';c=getchar()) if(c=='-') f=0; for(;'0'<=c&&c<='9';c=getchar()) x=(x<<1)+(x<<3)+(c^48); x=(f?x:~x+1); } vector<int>e[N]; stack<int>sta; queue<int> q; int n,m,s,p,bar,ans,sccnt,tot; int from[N],to[N],w[N],dfn[N],low[N],color[N],siz[N],d[N]; bool v[N],ins[N]; void tarjan(int x) { dfn[x]=low[x]=++tot; sta.push(x),ins[x]=1; for(int y:e[x]) { if(!dfn[y]) tarjan(y),low[x]=min(low[x],low[y]); else if(ins[y]) low[x]=min(low[x],dfn[y]); } if(dfn[x]==low[x]) { int y;++sccnt; while(y!=x) y=sta.top(), sta.pop(), ins[y]=0, color[y]=sccnt, siz[sccnt]+=w[y]; } } void spfa(int s) { q.push(s); d[s]=siz[s]; v[s]=1; while(!q.empty()) { int x=q.front(); q.pop(); v[x]=0; for(int y:e[x]) { if(d[y]<d[x]+siz[y]) { d[y]=d[x]+siz[y]; if(!v[y]) q.push(y),v[y]=1; } } } } signed main() { #ifndef ONLINE_JUDGE freopen("in.txt","r",stdin); freopen("out.txt","w",stdout); #endif read(n),read(m); for(int i=1;i<=m;i++) read(from[i]),read(to[i]), e[from[i]].push_back(to[i]); for(int i=1;i<=n;i++) read(w[i]); for(int i=1;i<=n;i++) if(!dfn[i]) tarjan(i); memset(e,0,sizeof(e)); for(int i=1;i<=m;i++) if(color[from[i]]!=color[to[i]]) e[color[from[i]]].push_back(color[to[i]]); read(s),read(p); spfa(color[s]); for(int i=1;i<=p;i++) read(bar),ans=max(ans,d[color[bar]]); cout<<ans; }
但是离谱的是,把小于号改成大于号也对,跑最短路也对了???,
memset(d,0x3f,sizeof(d)); q.push(s); d[s]=siz[s]; v[s]=1; while(!q.empty()) { int x=q.front(); q.pop(); v[x]=0; for(int y:e[x]) { if(d[y]>d[x]+siz[y]) { d[y]=d[x]+siz[y]; if(!v[y]) q.push(y),v[y]=1; } } }
不要手残
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· AI技术革命,工作效率10个最佳AI工具