CodeForces 536D Tavas in Kansas

Luo Gu title page Portal & codeforces title page Portal

A and B are in a connected undirected FIG \ (G = (V, E ), | = m \ V | = n, | | E) a game to play, the node \ (I \) has a weight \ ( v_i \) . A, B respectively stand Node \ (A, B \) , operated in turn, selects one number for each operation \ (X \) , and then select all the shortest distance to the location of their \ (\ le x \) and had not been selected the point, of weights and put them to accumulate their scores, and chose to meet at least \ (1 \) points. Until the current players can not operate, the game is over. A is the upper hand, A, B are higher hopes his scoring and according to the optimal policy actions. Set A, the final score B respectively \ (sco_a, sco_b \) , then output \ (\ begin {cases} ` ` \ text {Cry ''} & sco_a <sco_b \\ `` \ text {Flowers ''} & sco_a `` sco_b \\ = \ {text Heart Break A ''} & sco_a> sco_b \ Cases End {} \) .

\(n\in\left[2,2\times10^3\right],m\in\left[n-1,10^5\right],a\ne b,v_i\in\left[-10^9,10^9\right]\)

First, run \ (2 \) times the Dijkstra (due \ (\ mathrm O \ left ( n ^ 2 \ right) \) can be had, it is not necessary to optimize the stack) is affirmative, the node is calculated for each \ (I \) to \ (a, b \) are the shortest path, referred to as \ (dis1_i, dis2_i \) .

Then difficult to find, in order to \ (A \) is the shortest distance, the possible presence of \ (dis1_i <dis1_j \) such that \ (J \) is selected from the group A and the \ (I \) have not been selected (the reason is simple), to \ (b \) is no different. Then we can simply describe a game in any possible situation: there is one and only all meet \ (dis1_x \ le i \) or \ (dis2_x \ le j \) is \ (x \) is selected, denoted \ (S (I, J) \) . Consider \ (dis1, dis2 \) discrete (because we only need to compare the relative sizes, and \ (dis1, dis2 \) comparison is independent of each other, so we do not retain the original value), this is clearly \ (\ forall S ( I, J), I, J \ n-Le \) , we can be attached to each position DP array, such that the number of states in the \ (\ mathrm O (n ^ 2) \) level.

Set \ (dp1_ {i, j} , dp2_ {i, j} \) respectively represent an initial situation is the situation when the \ (of S_ {I, J} \) , the first step A, B operation, A fraction obtained. The first step in considering the enumeration of the operation of the new players chose those nodes (these nodes can not have been selected by another player), is about \ (i / j \) increased the number, then move on to the next situation. State transition equation:

\[\begin{cases}dp1_{i,j}=\max\limits_{\sum\limits_{o=i+1}^k\sum\limits_{dis1_p=o}[dis2_p>j]>0}\left\{dp2_{k,j}+\sum\limits_{o=i+1}^k\sum\limits_{dis1_p=o}[dis2_p>j]v_p\right\}\\dp2_{i,j}=\min\limits_{\sum\limits_{o=j+1}^k\sum\limits_{dis2_p=o}[dis1_p>i]>0}\left\{dp1_{i,k}\right\}\end{cases}\]

Such \ (1 \) secondary transfer is clearly \ (\ mathrm O (n) \) , the overall complexity \ (\ mathrm O \ left (n-^. 3 \ right) \) , will be fried. Section and which has noted equation, and then pre-prefix \ (Cnt1_ {i, j} = \ sum \ limits_ {k = 1} ^ i \ sum \ limits_ {dis1_o = k} [dis2_o> j], Sum1_ { i, j} = \ sum \ limits_ {k = 1} ^ i \ sum \ limits_ {dis1_o = k} [dis2_o> j] v_o, Cnt2_ {i, j} = \ sum \ limits_ {k = 1} ^ i \ SUM \ limits_ dis2_o = {K} [dis1_o> J] \) , the equation becomes:

\[\begin{cases}dp1_{i,j}=\max\limits_{Cnt1_{k,j}>Cnt1_{i,j}}\left\{dp2_{k,j}+Sum1_{k,j}-Sum1_{i,j}\right\}=\max\limits_{Cnt1_{k,j}>Cnt1_{i,j}}\left\{dp2_{k,j}+Sum1_{k,j}\right\}-Sum1_{i,j}\\dp2_{i,j}=\min\limits_{Cnt2_{i,k}>Cnt2_{i,j}}\left\{dp1_{i,k}\right\}\end{cases}\]

First be clear, when the DP is based on \ (i, j \) of reverse recursion (since only \ (i '\ i GE, J' \ GE J \) , \ (S (i, J) \) before It may be transferred to \ (S (I ', J') \) ). Difficult to find, \ (DP1 \) transfer equations, decision variables \ (K \) ranges must be an interval, set it to \ ([k _ {\ min }, k _ {\ max}] \) , then if \ (J \) is fixed, with (I \) \ drops, \ (K _ {\ max} = | DIS1 | \) constant established, \ (K _ {\ min} \) monotonically rise. Thus, it can be two-pointers, we can maintain the \ (now1, mx1 \) array, \ (now1_o, mx1_o \) means that when (j = o \) \ When the current \ (k _ {\ min} \ ) , all the largest decision \ (dp2_ {K, K {J} + Sum1_, J} \) , \ (I \) is reduced by \ (1 \) , the will \ (now1_j \)Reduce the number and updates \ (mx1_j \) . To \ (dp2 \) similar treatment, maintenance \ (now2, Mn2 \) .

Final comparison \ (dp1_ {0,0} \) and \ (\ sum \ limits_ {i = 1} ^ nv_i-dp1_ {0,0} \) size can. There on the border, that is, can not be transferred to any situation DP value \ (0 \) .

With a two-pointers, the time complexity is calculated for each DP value equal share \ (\ mathrm O (. 1) \) , plus the first Dijkstra, overall complexity is \ (\ mathrm O \ left ( n ^ 2 \ right) \) a.

Paste the code below:

/*
数据不清空,爆零两行泪。
多测不读完,爆零两行泪。
边界不特判,爆零两行泪。
贪心不证明,爆零两行泪。
D P 顺序错,爆零两行泪。
大小少等号,爆零两行泪。
变量不统一,爆零两行泪。
越界不判断,爆零两行泪。
调试不注释,爆零两行泪。
溢出不 l l,爆零两行泪。
*/
#include<bits/stdc++.h>
using namespace std;
#define int long long//防爆int 
#define mp make_pair
#define X first
#define Y second
#define pb push_back
const int inf=0x3f3f3f3f3f3f3f3f; 
const int N=2000;
int n/*点数*/,m/*边数*/,a/*A所在节点*/,b/*B所在节点*/;
int v[N+1];//点权 
vector<pair<int,int> > nei[N+1];//邻接表 
int dis1[N+1],dis2[N+1];//到a、b的最短距离 
bool vis[N+1]; 
void dijkstra(int x,int dis[]){//Dijkstra求dis1,dis2 
    for(int i=1;i<=n;i++)dis[i]=inf;
    dis[x]=0;
    memset(vis,0,sizeof(vis));
    while(true){
        pair<int,int> mn(inf,0);
        for(int j=1;j<=n;j++)if(!vis[j])mn=min(mn,mp(dis[j],j));
        int y=mn.Y;
        if(!y)break;
        vis[y]=true;
        for(int j=0;j<nei[y].size();j++){
            int z=nei[y][j].X,len=nei[y][j].Y;
            dis[z]=min(dis[z],dis[y]+len);
        }
    }
//  printf("dis=");for(int i=1;i<=n;i++)cout<<dis[i]<<" ";puts("");
}
vector<int> nums1,nums2;//离散化辅助数组 
vector<int> hav1[N+1],hav2[N+1];//hav1[i]中存储所有满足dis1[x]=i(离散化之后)的节点x,hav2类似 
void discrete(vector<int> &nums,int dis[],vector<int> hav[]){//离散化 
    nums.pb(-1);//比任何距离都小 
    for(int i=1;i<=n;i++)nums.pb(dis[i]);
    sort(nums.begin(),nums.end());
    nums.resize(unique(nums.begin(),nums.end())-nums.begin());
    for(int i=1;i<=n;i++)hav[dis[i]=lower_bound(nums.begin(),nums.end(),dis[i])-nums.begin()].pb(i);
}
int Cnt1[N+1][N+1],Sum1[N+1][N+1],Cnt2[N+1][N+1];//前缀和 
int now1[N+1],now2[N+1],mx1[N+1],mn2[N+1];//优化DP的two-pointers数组 
int dp1[N+1][N+1],dp2[N+1][N+1];//DP数组 
signed main(){
    cin>>n>>m>>a>>b;
    int sum=0;//所有点权和 
    for(int i=1;i<=n;i++)cin>>v[i],sum+=v[i];
    while(m--){
        int x,y,z;
        cin>>x>>y>>z;
        nei[x].pb(mp(y,z));nei[y].pb(mp(x,z));
    }
    dijkstra(a,dis1);dijkstra(b,dis2);//求出距离数组 
    discrete(nums1,dis1,hav1);discrete(nums2,dis2,hav2);//离散化距离数组 
    for(int i=1;i<nums1.size();i++)for(int j=0;j<nums2.size();j++){//预处理Cnt1,Sum1 
        Cnt1[i][j]=Cnt1[i-1][j];Sum1[i][j]=Sum1[i-1][j];
        for(int k=0;k<hav1[i].size();k++){
            bool ok=dis2[hav1[i][k]]>j;
            Cnt1[i][j]+=ok;Sum1[i][j]+=ok*v[hav1[i][k]];
        }
    }
    for(int i=1;i<nums2.size();i++)for(int j=0;j<nums1.size();j++){//预处理Cnt2 
        Cnt2[i][j]=Cnt2[i-1][j];
        for(int k=0;k<hav2[i].size();k++)Cnt2[i][j]+=dis1[hav2[i][k]]>j;
    }
    for(int i=0;i<=n;i++)now1[i]=nums1.size(),now2[i]=nums2.size(),mx1[i]=-inf,mn2[i]=inf;//赋初始值 
    for(int i=nums1.size()-1;~i;i--)for(int j=nums2.size()-1;~j;j--){//按i,j倒序DP 
        while(now1[j]&&Cnt1[now1[j]-1][j]>Cnt1[i][j])now1[j]--,mx1[j]=max(mx1[j],dp2[now1[j]][j]+Sum1[now1[j]][j]);//two-pointers 
        dp1[i][j]=mx1[j]>-inf?/*能转移?*/mx1[j]-Sum1[i][j]/*按方程来*/:0/*为0*/;
        while(now2[i]&&Cnt2[now2[i]-1][i]>Cnt2[j][i])now2[i]--,mn2[i]=min(mn2[i],dp1[i][now2[i]]);//同上2行 
        dp2[i][j]=mn2[i]<inf?mn2[i]:0;//同上2行 
//      printf("dp1[%lld][%lld]=%lld dp2[%lld][%lld]=%lld\n",i,j,dp1[i][j],i,j,dp2[i][j]);
    }
    int ans=dp1[0][0];//A的最优得分 
    puts(ans<sum-ans?"Cry":ans==sum-ans?"Flowers":"Break a heart");
    return 0;
}
/*1
4 4
1 2
3 2 5 -11
1 4 2
3 4 2
3 1 5
3 2 1
*/
/*2
5 4
1 2
2 2 -5 -4 6
1 2 4
2 3 5
2 4 2
4 5 2
*/
/*3
2 1
1 2
-5 -5
1 2 10
*/

Guess you like

Origin www.cnblogs.com/ycx-akioi/p/CodeForces-536D.html