最美情侣中文字幕电影,在线麻豆精品传媒,在线网站高清黄,久久黄色视频

歡迎光臨散文網(wǎng) 會員登陸 & 注冊

題解 ABC261H【Game on Graph】

2022-11-10 11:29 作者:限量版范兒  | 我要投稿

problem

Takahashi 和 Aoki 正在一張?\(n\)?個點,\(m\)?條邊的帶權(quán)有向圖上玩游戲。游戲規(guī)則如下:

  • 有一顆最初在?\(s\)?點的棋子。雙方輪流移動這顆棋子,Takahashi 先手。

  • 每一次移動都可以使棋子從邊的一端移動到另一端。如果無法移動,也就是不存在出邊時,游戲結(jié)束。

  • 定義一局游戲的得分為棋子移動路徑上的邊權(quán)之和。如果經(jīng)過一條邊多次,邊權(quán)也計算多次。

Takahashi 想要最小化游戲的得分,但 Aoki 想要最大化得分。請輸出在最優(yōu)策略下游戲的最終得分。特別地,如果游戲無法結(jié)束,請輸出?INFINITY。

\(1\le n\le 2\times 10^5,\ 0\le m\le 2\times 10^5\)。有向圖保證沒有重邊和自環(huán),但?不保證無環(huán)。

solution

考慮拆點,把圖上的點?\(u\)?拆成?\(u,u+n\)?兩個點,分別表示走到這個點時高橋 / 青木先手。那么所有的邊?\((u,v)\)?也拆成?\((u,v+n),(u+n,v)\)?兩條??梢园l(fā)現(xiàn)這樣建出的圖是二分圖。

考慮在反圖上 DP:令?\(f_u\)?表示在這個點上的得分。


\[f_u=\begin{cases}
\min_{v}\{f_v+w_{u,v}\},\quad&(u\leq n,v>n,\text{以下稱為白點}),\\
\max_{v}\{f_v+w_{u,v}\},\quad&(u>n,v\leq n,\text{以下稱為黑點}).
\end{cases}\]

初始時所有的葉子答案為?\(0\),最終答案?\(f_s\)。但是這個 DP 有后效性。

我們假想我們從小到大拿白點出來更新,考慮幾個貪心:

  1. 當一個白點被拿出來的時候,它一定是最小的。

感性理解:邊權(quán)非負,如果它取出來不是最小,那么最小的值應(yīng)該在后面繞回來的時候更新,這個時候已經(jīng)比取出時的大了。

  1. 當且僅當所有能更新一個黑點的白點取完后,這個黑點能更新其它白點的答案。

感性理解:不然你如何說明這個黑點取得的答案是最大值?

于是我們用一個堆放白點,從小到大取白點,用白點更新黑點,如果一個黑點已經(jīng)被完全更新,就用黑點去更新白點,將更新后的白點放入堆中。

整個算法和 Dijkstra 很像。復(fù)雜度?\(O(m\log m)\)

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; }

鏈接:https://www.dianjilingqu.com/607172.html

題解 ABC261H【Game on Graph】的評論 (共 條)

分享到微博請遵守國家法律
通州区| 龙州县| 石狮市| 宁陕县| 太仓市| 平湖市| 衡东县| 连山| 大同县| 沙田区| 葵青区| 清新县| 白河县| 醴陵市| 吕梁市| 宁化县| 德惠市| 会昌县| 柳江县| 资源县| 通山县| 兴业县| 宾川县| 观塘区| 厦门市| 哈尔滨市| 伊吾县| 宜章县| 兴安县| 津市市| 新郑市| 新乐市| 桂林市| 潢川县| 微博| 宁都县| 肥乡县| 浦东新区| 武安市| 铜陵市| 景谷|