[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. shiro 单点登录原理 实例

    原创 2017年02月08日 17:39:55 4006 Shiro 1.2开始提供了Jasig CAS单点登录的支持,单点登录主要用于多系统集成,即在多个系统中,用户只需要到一个中央服务器登录一次即 ...

  2. python之字符编码

    1.以什么编码存的就以什么编码取出; 内存固定使用unicode编码; 我们可以控制的编码是往硬盘存放或者基于网络传输选择编码. 2.数据是最先产生于内存中,是unicode格式,要想传输需要转成by ...

  3. Vue自定义class覆盖第三方组件原有样式

    一个vue文件可以写多个<style></style>, 如果在style加上socped代表本组件的样式,不污染全局. 如果需要覆盖第三方组件样式,则不能加scoped,因此 ...

  4. js中的原型

    一:原型属性 函数本身也是一个包含了方法和属性的对象. 定义一个函数foo(),访问其他对象一样访问该函数的属性: function foo(a, b) { return a * b; } foo.l ...

  5. 【第一部分】07Leetcode刷题

    二.寻找旋转排序数组中的最小值 题目:153. Find Minimum in Rotated Sorted Array C++ Soution 1: class Solution { public: ...

  6. PEM routines:PEM_read_bio:no start line

    https://blog.csdn.net/xiejunna/article/details/71151006 在放置证书后,运行nodejs抛异常:PEM routines:PEM_read_bio ...

  7. Nginx安装配置&反向代理

    使用Nginx作为前端服务能够更快更及时的响应静态页面.js.图片等,当客户端请求访问动态页面时由Nginx的反向代理给Apache处理,Apache处理完再交予Nginx返回给客户端. Nginx更 ...

  8. 用vi编辑文件

    原文:https://www.ibm.com/developerworks/library/l-lpic1-103-8/index.html Overview In this article, lea ...

  9. Hadoop的namenode的管理机制,工作机制和datanode的工作原理

    HDFS前言: 1) 设计思想 分而治之:将大文件.大批量文件,分布式存放在大量服务器上,以便于采取分而治之的方式对海量数据进行运算分析: 2)在大数据系统中作用: 为各类分布式运算框架(如:mapr ...

  10. AndroidStudio在线搜索最新版本的依赖库

    操作步骤 打开File–>Project Structure 选中当前项目,点击Denpendencies标签 点击+,选Library dependency 打开界面如下: 输入想要的依赖库部 ...