[CF536D]Tavas in Kansas

题目大意:

一张\(n(n\le2000)\)个点,\(m(m\le10^5)\)条边的无向带权连通图(权值可以为负)。A、B两人分别在\(s,t\)点进行博弈。A先手,每次每人可以选择一个数\(x\),并取走到当前位置距离\(\le x\)的点,自己的得分加上这些点的权值之和。每次至少取走一个点,去过的点不能再取。取完所有的点后,得分最高者胜。若每个人都按照最后策略进行游戏,求最后的赢家。

思路:

首先求\(s,t\)的单元最短路。对于每个点,我们可以知道它是离\(s\)第\(x\)远的点,离\(t\)第\(y\)远的点。我们将它当作二维平面上的点\((x,y)\),那么游戏就相当于A每次取一行,B每次取一列。

用\(f[i][j][0/1]\)表示取前\(i\)行,前\(j\)列,最后一个人是A还是B,此时\(A-B\)在最优策略下的得分。

转移方程显然,反着DP可以少一些特判。

源代码:

#include<cstdio>
#include<cctype>
#include<vector>
#include<climits>
#include<functional>
#include<ext/pb_ds/priority_queue.hpp>
inline int getint() {
register char ch;
register bool neg=false;
while(!isdigit(ch=getchar())) neg|=ch=='-';
register int x=ch^'0';
while(isdigit(ch=getchar())) x=(((x<<2)+x)<<1)+(ch^'0');
return neg?-x:x;
}
typedef long long int64;
const int N=2001;
int n,w[N],s[2],tot[2],cnt[2][N][N];
struct Edge {
int to,w;
};
std::vector<Edge> e[N];
inline void add_edge(const int &u,const int &v,const int &w) {
e[u].push_back((Edge){v,w});
e[v].push_back((Edge){u,w});
}
int64 dis[2][N],hash[N],f[N][N][2],sum[2][N][N];
struct Vertex {
int id;
int64 d;
bool operator > (const Vertex &rhs) const {
return d>rhs.d;
}
};
__gnu_pbds::priority_queue<Vertex,std::greater<Vertex> > q;
__gnu_pbds::priority_queue<Vertex,std::greater<Vertex> >::point_iterator p[N];
inline void dijkstra(const int &s,int64 dis[]) {
for(register int i=1;i<=n;i++) {
p[i]=q.push((Vertex){i,dis[i]=i==s?0:LLONG_MAX});
}
while(!q.empty()) {
const int x=q.top().id;
q.pop();
for(auto &j:e[x]) {
const int &y=j.to,&w=j.w;
if(dis[x]+w<dis[y]) {
q.modify(p[y],(Vertex){y,dis[y]=dis[x]+w});
}
}
}
}
int main() {
n=getint();
const int m=getint();
s[0]=getint(),s[1]=getint();
for(register int i=1;i<=n;i++) {
w[i]=getint();
}
for(register int i=0;i<m;i++) {
const int u=getint(),v=getint();
add_edge(u,v,getint());
}
for(register int i=0;i<2;i++) {
dijkstra(s[i],dis[i]);
std::copy(&dis[i][1],&dis[i][n]+1,&hash[1]);
std::sort(&hash[1],&hash[n]+1);
tot[i]=std::unique(&hash[1],&hash[n]+1)-&hash[1];
for(register int j=1;j<=n;j++) {
dis[i][j]=std::lower_bound(&hash[1],&hash[tot[i]]+1,dis[i][j])-hash;
}
}
for(register int i=1;i<=n;i++) {
sum[0][dis[0][i]][dis[1][i]]+=w[i];
sum[1][dis[0][i]][dis[1][i]]+=w[i];
cnt[0][dis[0][i]][dis[1][i]]++;
cnt[1][dis[0][i]][dis[1][i]]++;
}
for(register int i=1;i<=tot[0];i++) {
for(register int j=1;j<=tot[1];j++) {
sum[0][i][j]+=sum[0][i][j-1];
sum[1][i][j]+=sum[1][i-1][j];
cnt[0][i][j]+=cnt[0][i][j-1];
cnt[1][i][j]+=cnt[1][i-1][j];
}
}
for(register int i=tot[0];i>=0;i--) {
for(register int j=tot[1];j>=0;j--) {
if(i==tot[0]&&j==tot[1]) continue;
if(i!=tot[0]) {
const int64 s=sum[0][i+1][tot[1]]-sum[0][i+1][j];
if(cnt[0][i+1][tot[1]]-cnt[0][i+1][j]) {
f[i][j][0]=std::max(f[i+1][j][0],f[i+1][j][1])+s;
} else {
f[i][j][0]=f[i+1][j][0];
}
}
if(j!=tot[1]) {
const int64 s=sum[1][tot[0]][j+1]-sum[1][i][j+1];
if(cnt[1][tot[0]][j+1]-cnt[1][i][j+1]) {
f[i][j][1]=std::min(f[i][j+1][0],f[i][j+1][1])-s;
} else {
f[i][j][1]=f[i][j+1][1];
}
}
}
}
const int64 ans=f[0][0][0];
if(ans>0) puts("Break a heart");
if(ans==0) puts("Flowers");
if(ans<0) puts("Cry");
return 0;
}

[CF536D]Tavas in Kansas的更多相关文章

  1. CF536D Tavas in Kansas(博弈论+dp)

    貌似洛谷的题面是没有翻译的 QWQ 大致题面是这个样子,但是可能根据题目本身有不同的地方 完全懵逼的一个题(果然博弈论就是不一样) 首先,我们考虑把题目转化成一个可做的模型. 我们分别从\(s\)和\ ...

  2. CodeForces 536D Tavas in Kansas

    洛谷题目页面传送门 & CodeForces题目页面传送门 A和B在一张无向连通图\(G=(V,E),|V|=n,|E|=m\)上玩一个游戏,节点\(i\)有一个权值\(v_i\).A.B分别 ...

  3. Codeforces 536D - Tavas in Kansas(dp)

    Codeforces 题目传送门 & 洛谷题目传送门 其实这题本该 2019 年 12 月就 AC 的(详情请见 ycx 发此题题解的时间),然鹅鸽到了现在-- 首先以 \(s,t\) 分别为 ...

  4. C. Tavas and Karafs 二分查找+贪心

    C. Tavas and Karafs #include <iostream> #include <cstdio> #include <cstring> #incl ...

  5. CF Tavas and Karafs (二分)

    Tavas and Karafs time limit per test 2 seconds memory limit per test 256 megabytes input standard in ...

  6. CF Tavas and Nafas

     Tavas and Nafas time limit per test 1 second memory limit per test 256 megabytes input standard inp ...

  7. Codeforces Round #299 (Div. 1)C. Tavas and Pashmaks (凸壳)

    C. Tavas and Pashmaks   Tavas is a cheerleader in the new sports competition named "Pashmaks&qu ...

  8. Codeforces 535D - Tavas and Malekas

    535D - Tavas and Malekas 题目大意:给你一个模板串,给你一个 s 串的长度,告诉你 s 串中有 m 个模板串并告诉你,他们的其实位置, 问你这样的 s 串总数的多少,答案对1e ...

  9. Codeforces 535C - Tavas and Karafs

    535C - Tavas and Karafs 思路:对于满足条件的r,max(hl ,hl+1 ,hl+2 ,......,hr )<=t(也就是hr<=t)且∑hi<=t*m.所 ...

随机推荐

  1. Mysql 查看连接数,状态 最大并发数

    show status like '%max_connections%'; ##mysql最大连接数set global max_connections=1000 ##重新设置show variabl ...

  2. Spring Cloud与Spring Boot版本匹配关系

    Spring Cloud是什么? “Spring Cloud provides tools for developers to quickly build some of the common pat ...

  3. 关于金蝶k3 wise供应生门户登陆界面屏蔽业务账套多余功能模块设置方法

    关于金蝶k3 wise供应生门户登陆界面屏蔽业务账套多余功能模块设置方法 1. 找到以下路径 ...\Kingdee\K3ERP\KDHR\SITEFILE\WEBUI\ 找到“Login.aspx” ...

  4. 关于文件I/o的原子操作

    [摘自<Linux/Unix系统编程手册>] 所有系统调用都是以原子操作方式执行的.这里是指内核保证了某系统调用中的所有步骤会作为独立操作而一次性执行,其间不会为其它进程或线程所中断. 原 ...

  5. ynoi2018

    题解: 全分块是啥操作啊.. 而且都好难.. 1.未来日记 这个比较简单 对每个块开个线段树维护权值 $n\sqrt{n}logn$ 这个会炸空间 并不能做... 但还是说一下做法 首先考虑分块 然后 ...

  6. python之squid实现免费 IP代理 (windows win7 单机 本机 本地 正向代理 区分 HTTPS)

    0.目录 1.思路2.windows安装3.相关命令行4.简单配置和初步使用5.问题:squid是否支持HTTPS6.问题:配置多个代理条目,相同ip不同port报错7.问题:根据代理请求区分HTTP ...

  7. mysql字符集问题汇总

    1.设置mysql字符集:在my.ini中添加以下设置,没有my.ini可以将my_default.ini改成他.character-set-server=utf8[client]loose-defa ...

  8. 修改ini文件的批处理

    用VBS更简单: vbs代码: On Error Resume Next Dim Fso,TxtFl,Str Set Fso = CreateObject("Scripting.FileSy ...

  9. ELK 环境搭建4-Kafka + zookeeper

    一.安装前准备 1.节点 192.168.30.41 192.168.30.42 192.168.30.43 2.操作系统: Centos7.5 3.安装包 a.java8: jdk-8u181-li ...

  10. windows 设置开机启动,启动项

    第一步ctrl+R输入以下任意一个 方法一: C:\ProgramData\Microsoft\Windows\Start Menu\Programs\StartUp 方法二: shell:start ...