zoukankan      html  css  js  c++  java
  • CF536D Tavas in Kansas

    题意

    • 给定(n)个点(m)条边带点权的无向联通图
    • A在(s)点,B在(t)点,每人最初的值为0,每人每次可以选择一个距离(d),将所有与他自己距离不超过(d)的点标记
    • 然后将自己的值加上本次所有标记了的点的权值,每次至少标记一个点,直到所有点都标记为止,最后值大的人获胜

    博弈论,将每个点到另外两点的距离跑出来,然后扔到坐标系里,发现每次选择相当于将每个人的直线向下/右平移,标记所有未标记的点
    考虑记(f_{n, m, 0/1})表示当前可以选(n~N,m~M)点,先手/后手能得到的最大权值,然后从后往前以及从下往上转移就好了

    #include<bits/stdc++.h>
    #define For(i, a, b) for(int i = (a), en = (b); i <= en; ++i)
    #define Rof(i, a, b) for(int i = (a), en = (b); i >= en; --i)
    #define Tra(u, i) for(int i = hd[u]; ~i; i = e[i].net)
    #define LL long long
    #define DD double
    #define LD long double
    #define pb push_back
    #define mp make_pair
    #define fir first
    #define sec second
    #define inf 0x3f3f3f3f
    #define Inf 0x3f3f3f3f3f3f3f3f
    #define eps 1e-12
    #define maxn 2000
    #define maxm 100000
    using namespace std;
    
    int n, m, s, t, hd[maxn + 5], len = 0, a[maxn + 5], cnt[2];
    LL sum[maxn + 5][maxn  + 5], b[2][maxn + 5], ma[maxn + 5][maxn + 5], f[2][maxn + 5][maxn + 5], mx[maxn + 5], now[maxn + 5];
    struct Edge{int v, w, net;} e[2 * maxn + 5];
    void add(int u, int v, int w){e[len] = (Edge){v, w, hd[u]}; hd[u] = len++;}
    
    LL dis[2][maxn + 5];
    void dij(int x, int ty){
    	memset(dis[ty], inf, sizeof dis[ty]); dis[ty][x] = 0;
    	priority_queue<pair<LL, int> > q;
    	q.push(mp(0, x));
    	while(q.size()){
    		int u = q.top().sec; q.pop();
    		Tra(u, i){
    			int v = e[i].v, w = e[i].w;
    			if(dis[ty][v] <= dis[ty][u] + w) continue;
    			dis[ty][v] = dis[ty][u] + w;
    			q.push(mp(-dis[ty][v], v));
    		}
    	}
    }
    
    int main(){
    	//freopen("in", "r", stdin);
    	memset(hd, -1, sizeof hd);
    	scanf("%d %d %d %d", &n, &m, &s, &t);
    	For(i, 1, n) scanf("%d", &a[i]);
    	For(i, 1, m){
    		int u, v, w; scanf("%d %d %d", &u, &v, &w);
    		add(u, v, w); add(v, u, w);
    	}
    	
    	dij(s, 0);
    	For(i, 1, n) b[0][++cnt[0]] = dis[0][i];
    	sort(b[0] + 1, b[0] + cnt[0] + 1);
    	cnt[0] = unique(b[0] + 1, b[0] + cnt[0] + 1) - b[0] - 1;
    	For(i, 1, n) dis[0][i] = lower_bound(b[0] + 1, b[0] + cnt[0] + 1, dis[0][i]) - b[0];
    
    	dij(t, 1);
    	For(i, 1, n) b[1][++cnt[1]] = dis[1][i];
    	sort(b[1] + 1, b[1] + cnt[1] + 1);
    	cnt[1] = unique(b[1] + 1, b[1] + cnt[1] + 1) - b[1] - 1;
    	For(i, 1, n) dis[1][i] = lower_bound(b[1] + 1, b[1] + cnt[1] + 1, dis[1][i]) - b[1];
    
    	For(i, 1, n) sum[dis[0][i]][dis[1][i]] += a[i], ma[dis[0][i]][dis[1][i]] = 1;
    
    	/*cout << cnt[0] << " " << cnt[1] << endl;
    	For(i, 1, cnt[0]){
    		For(j, 1, cnt[1]) cout << sum[i][j] << " ";
    		cout << endl;
    	}
    	cout << endl;*/
    	
    	Rof(i, cnt[0], 1) Rof(j, cnt[1], 1){
    		sum[i][j] += sum[i + 1][j] + sum[i][j + 1] - sum[i + 1][j + 1];
    		ma[i][j] += ma[i + 1][j] + ma[i][j + 1] - ma[i + 1][j + 1];
    	}
    
    	For(i, 1, cnt[1]) now[i] = cnt[0], mx[i] = cnt[0] + 1;
    	Rof(i, cnt[0], 1){
    		int nowi = cnt[1], mxi = cnt[1] + 1;
    		Rof(j, cnt[1], 1){
    			while(now[j] > i && ma[i][j] - ma[now[j]][j]){
    				if(sum[now[j]][j] - f[1][now[j]][j] + sum[i][j] - sum[now[j]][j] > sum[mx[j]][j] - f[1][mx[j]][j] + sum[i][j] - sum[mx[j]][j]) mx[j] = now[j];
    				now[j]--;
    			}
    			f[0][i][j] = sum[mx[j]][j] - f[1][mx[j]][j] + sum[i][j] - sum[mx[j]][j];
    			
    			while(nowi > j && ma[i][j] - ma[i][nowi]){
    				if(sum[i][nowi] - f[0][i][nowi] + sum[i][j] - sum[i][nowi] >= sum[i][mxi] - f[0][i][mxi] + sum[i][j] - sum[i][mxi]) mxi = nowi;
    				nowi--;
    			}
    			f[1][i][j] = sum[i][mxi] - f[0][i][mxi] + sum[i][j] - sum[i][mxi];
    		}
    	}
    	
    	LL tem = f[0][1][1] - (sum[1][1] - f[0][1][1]);
    	if(tem > 0) puts("Break a heart");
    	else if(tem < 0) puts("Cry");
    	else puts("Flowers");
    	return 0;
    }
    
  • 相关阅读:
    Overloaded的方法是否可以改变返回值的类型
    parseXXX的用法
    java的类型转换问题。int a = 123456;short b = (short)a;System.out.println(b);为什么结果是-7616?
    UVA 10405 Longest Common Subsequence(简单DP)
    POJ 1001 Exponentiation(大数处理)
    POJ 2318 TOYS(计算几何)(二分)
    POJ 1265 Area (计算几何)(Pick定理)
    POJ 3371 Flesch Reading Ease (模拟题)
    POJ 3687 Labeling Balls(拓扑序列)
    POJ 1094 Sorting It All Out(拓扑序列)
  • 原文地址:https://www.cnblogs.com/lprdsb/p/13769458.html
Copyright © 2011-2022 走看看