题解 ABC261H【Game on Graph】
posted on 2022-10-28 08:41:23 | under 题解 | source
problem
Takahashi 和 Aoki 正在一张
- 有一颗最初在
点的棋子。双方轮流移动这颗棋子,Takahashi 先手。 - 每一次移动都可以使棋子从边的一端移动到另一端。如果无法移动,也就是不存在出边时,游戏结束。
- 定义一局游戏的得分为棋子移动路径上的边权之和。如果经过一条边多次,边权也计算多次。
Takahashi 想要最小化游戏的得分,但 Aoki 想要最大化得分。请输出在最优策略下游戏的最终得分。特别地,如果游戏无法结束,请输出 INFINITY
。
solution
考虑拆点,把图上的点
考虑在反图上 DP:令
初始时所有的叶子答案为
我们假想我们从小到大拿白点出来更新,考虑几个贪心:
- 当一个白点被拿出来的时候,它一定是最小的。
感性理解:边权非负,如果它取出来不是最小,那么最小的值应该在后面绕回来的时候更新,这个时候已经比取出时的大了。
- 当且仅当所有能更新一个黑点的白点取完后,这个黑点能更新其它白点的答案。
感性理解:不然你如何说明这个黑点取得的答案是最大值?
于是我们用一个堆放白点,从小到大取白点,用白点更新黑点,如果一个黑点已经被完全更新,就用黑点去更新白点,将更新后的白点放入堆中。
整个算法和 Dijkstra 很像。复杂度
code
#include <queue>
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
typedef long long LL;
template<int N,int M,class T=int> struct graph{
int head[N+10],nxt[M*2+10],cnt;
struct edge{
int u,v; T w;
edge(int u=0,int v=0,T w=0):u(u),v(v),w(w){}
} e[M*2+10];
graph(){memset(head,cnt=0,sizeof head);}
edge& operator[](int i){return e[i];}
void add(int u,int v,T w=0){e[++cnt]=edge(u,v,w),nxt[cnt]=head[u],head[u]=cnt;}
void link(int u,int v,T w=0){add(u,v,w),add(v,u,w);}
};
int n,m,s,deg[400010];
LL f[400010];
bool vis[400010];
graph<400010,400010,int> g;
priority_queue<pair<LL,int>,vector<pair<LL,int>>,greater<pair<LL,int>>> q;
void expand(int u){//u>n
for(int i=g.head[u];i;i=g.nxt[i]){
int v=g[i].v;
if(f[v]>f[u]+g[i].w) q.push({f[v]=f[u]+g[i].w,v});
}
}
LL dp(){
for(int i=1;i<=n;i++) f[i]=1e18;
for(int i=n+1;i<=n*2;i++) f[i]=-1e18;
for(int i=1;i<=n;i++) if(!deg[i]) q.push({f[i]=0,i});
for(int i=n+1;i<=n*2;i++) if(!deg[i]) f[i]=0,expand(i);
memset(vis,0,sizeof vis);
while(!q.empty()){
int u=q.top().second; q.pop();
if(vis[u]) continue; vis[u]=1;
for(int i=g.head[u];i;i=g.nxt[i]){
int v=g[i].v;
if(f[v]<f[u]+g[i].w) f[v]=f[u]+g[i].w;
if(!--deg[v]) expand(v);
}
}
return f[s];
}
int main(){
scanf("%d%d%d",&n,&m,&s);
for(int i=1,u,v,w;i<=m;i++){
scanf("%d%d%d",&u,&v,&w);
g.add(v+n,u,w),g.add(v,u+n,w);
deg[u]++,deg[u+n]++;
}
LL res=dp();
if(res<1e18) printf("%lld\n",res);
else puts("INFINITY");
return 0;
}
本文来自博客园,作者:caijianhong,转载请注明原文链接:https://www.cnblogs.com/caijianhong/p/solution-ABC261H.html
分类:
solution
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 单线程的Redis速度为什么快?
· SQL Server 2025 AI相关能力初探
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 展开说说关于C#中ORM框架的用法!