Gym-101242B:Branch Assignment(最短路,四边形不等式优化DP)

Posted hua-dong

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Gym-101242B:Branch Assignment(最短路,四边形不等式优化DP)相关的知识,希望对你有一定的参考价值。

题意:要完成一个由s个子项目组成的项目,给b(b>=s)个部门分配,从而把b个部门分成s个组。分组完成后,每一组的任
意两个点之间都要传递信息。假设在(i,j)两个点间传送信息,要先把信息加密,然后快递员从i出发到总部,再加
密,在到j点。出于安全原因,每次只能携带一条消息。现在给出了道路网络、各个部门和总部的位置,请输出快
递员要走的最小总距离。
思路:求最短路dis,排序。 由排序不等式,dis相近的分到一组。 那么就是一个分组问题,可以用四边形不等式; 决策单调性DP; 二分+单调栈; 斜率优化。
#include<bits/stdc++.h>
#define s second
#define f first
#define ll long long
#define rep(i,a,b) for(int i=a;i<=b;i++)
using namespace std;
const int inf=1e9;
const int maxn=100010;
int Laxt[maxn],Next[maxn],To[maxn],Len[maxn],cnt;
int a[maxn],b[maxn],c[maxn],dis[maxn],N,M,S,B,s[5010][5010];
ll dp[5010][5010],sum[5010];
pair<int,int>p[maxn]; int vis[maxn];
void read(int &x)
    x=0; char c=getchar();
    while(c>9||c<0) c=getchar();
    while(c>=0&&c<=9) x=x*10+c-0,c=getchar();

void add(int u,int v,int l)

    Next[++cnt]=Laxt[u]; Laxt[u]=cnt;
    To[cnt]=v; Len[cnt]=l;

struct in
    int dis,u;
    in()
    in(int dd,int uu):dis(dd),u(uu)
    friend bool operator <(in w,in v)
        return w.dis>v.dis;
    
;
void SPFA()

    rep(i,1,M) swap(a[i],b[i]);
    cnt=0; rep(i,1,N) Laxt[i]=0,vis[i]=0,dis[i]=inf;
    rep(i,1,M) add(a[i],b[i],c[i]);
    priority_queue<in>q; q.push(in(0,B+1)); dis[B+1]=0;
    while(!q.empty())
        int u=q.top().u; q.pop(); vis[u]=0;
        for(int i=Laxt[u];i;i=Next[i])
            int v=To[i];if(dis[v]>dis[u]+Len[i])
                dis[v]=dis[u]+Len[i];
                if(!vis[v]) vis[v]=1,q.push(in(dis[v],v));
            
        
    

int main()

    while(~scanf("%d%d%d%d",&N,&B,&S,&M))
       rep(i,1,M) read(a[i]),read(b[i]),read(c[i]);
       SPFA();
       rep(i,1,B) p[i].s=i,p[i].f=dis[i];
       SPFA();
       rep(i,1,B) p[i].f+=dis[i];
       sort(p+1,p+B+1);
       rep(i,1,B) sum[i]=sum[i-1]+p[i].f;
       memset(s,0,sizeof(s));
       memset(dp,0x3f,sizeof(dp));
       dp[0][0]=0;
       rep(k,0,S) s[B+1][k]=B;
       rep(k,1,S)
         for(int i=B;i>=1;i--) 
            for(int j=s[i][k-1];j<=s[i+1][k]&&j<i;j++)
                if(dp[i][k]>dp[j][k-1]+1LL*(i-j-1)*(sum[i]-sum[j]))
                   dp[i][k]=dp[j][k-1]+1LL*(i-j-1)*(sum[i]-sum[j]);
                   s[i][k]=j;
                
            
          
       
       printf("%lld\n",dp[B][S]);
    
    return 0;

 

 

以上是关于Gym-101242B:Branch Assignment(最短路,四边形不等式优化DP)的主要内容,如果未能解决你的问题,请参考以下文章

Object.assign 的奇怪行为

Object.assign()用法讲解

Es6规范 Object.assign()的基本用法

Object.assign( )

js 合并多个对象 Object.assign

Object.assign