2023NOIP A层联测16 T3 货物运输

题目描述说这是一个仙人掌图,通常将问题转换为环和树的问题在使用圆方树来解决。

树解法

令 \(a_i=s_i-\frac{\sum s_i}{n}\) ,最终令 \(a_i=0\)。

通过树形 dp,从叶子节点向上转移,叶子节点要么向父亲拿资源,要么向父亲传资源,所以转移为:

\[a_{fa}+=a_i\\
ans+=w_i\times|a_i|
\]

环解法

令 \(a_i=s_i-\frac{\sum s_i}{n}\) ,最终令 \(a_i=0\)。

不妨设编号顺序为:\(1,2,3,\cdots,n\)。

\(x_i\) 表示点 \(i\) 向 \(i-1\) 运输了\(x_i\) 个单位的资源,若 \(x_i<0\) 那么是 \(i-1\) 向 \(i\) 运输,若 \(i=1\) 那么 \(1\) 向 \(n\) 运输。

有方程组:

\[\begin{cases}
a_1-x_1+x_2=0\\
a_2-x_2+x_3=0\\
a_3-x_3+x_4=0\\
\cdots\\
a_{n-1}-x_{n-1}+x_n\\
a_n-x_n+x_1=0
\end{cases}
\]

移项化简后,我们发现有 \(x_i=x_1-X_i\),若 \(i=1\),则 \(X_1=0\)(化简到这里实际上只需要前 \(n-1\) 条方程),其中 \(X_i\) 为常数。

那么答案为 \(\sum w_i|x_i|=\sum w_i|x_1-X_i|\)。

现在将问题转化为求出 \(x_1\) 的值,使得 \(\sum w_i |x_1 - X_i|\) 最小。对于 \(w_i = 1\) 的情况,\(x_1\) 直接取 \(X_i\) 的中位数。类似的,对于 \(w_i\) 没有限制的情况,可以看作有 \(w_i\) 个 \(X_i\),取 \(\sum w_i\) 个数的中位数。复杂度为排序的 \(O(n \log n)\)。

仙人掌

将一个环看成树上的一个点,环与环之间相邻的点看成边,依旧从叶子节点开始做。节点是环,使用环的解决方法,如果环缺少或多出值,先赊账在与父亲相连的点上(因为自己的儿子已经转移完了,多出或者少于都只可以传递或来自父亲),对于非环的边采用类似于树形 \(dp\) 的解决方法。

实现

可以先建出圆方树,一个方点对应一个环或者一条边,使用方点转移即可。

#include<bits/stdc++.h>
using namespace std; #define int long long const int maxn=1e6+5,maxm=1e6+5; struct node
{
int to,nxt;
}edge[maxn*4],tred[maxm]; int n,m,trtot,tot,tp,cok,tx,pj,ans;
int head[maxn],trhead[maxm],s[maxn],dfn[maxn],low[maxn],stk[maxn],sz[maxn],f[maxn]; vector<int>vec[maxm]; map<pair<int,int>,int>mp; void add(int &tot,int head[],node edge[],int x,int y)
{
tot++;
edge[tot].to=y;
edge[tot].nxt=head[x];
head[x]=tot;
} void tarjin(int u)//建圆方树
{
dfn[u]=low[u]=++cok;
stk[++tp]=u;
for(int i=head[u];i;i=edge[i].nxt)
{
int v=edge[i].to;
if(!dfn[v])
{
tarjin(v);
low[u]=min(low[u],low[v]);
if(low[v]>=dfn[u])
{
add(trtot,trhead,tred,++tx,u);
add(trtot,trhead,tred,u,tx);
vec[tx].push_back(u);
int x=0;
do
{
x=stk[tp--];
add(trtot,trhead,tred,tx,x);
add(trtot,trhead,tred,x,tx);
vec[tx].push_back(x);
}while(x!=v);
}
}
else low[u]=min(low[u],dfn[v]);
}
} void dfs2(int u)//遍历圆方树求答案
{
int sum=0;
for(int i=trhead[u];i;i=tred[i].nxt)
{
int v=tred[i].to;
if(v==f[u]) continue;
dfs2(v);
if(u>n) sum+=s[v];
}
if(u<=n) return ; if(vec[u].size()==2)//非环边直接转移
{
int son;
if(vec[u][0]==f[u]) son=vec[u][1];
else son=vec[u][0];
s[f[u]]+=s[son];
ans+=abs(s[son])*mp[make_pair(f[u],son)];
return ;
} priority_queue< pair<int,int>,vector< pair<int,int> >, greater< pair<int,int> > >que;//环边
while(!que.empty()) que.pop();
int cnt=vec[u].size();
sum+=s[f[u]];
int tmp=s[f[u]];
s[f[u]]=s[f[u]]-sum;
que.push(make_pair(0,mp[ make_pair(vec[u][0],vec[u][cnt-1]) ]));
int ct=0,sg=mp[ make_pair(vec[u][0],vec[u][cnt-1]) ];
for(int i=1;i<cnt;i++)
{
int w=mp[ make_pair(vec[u][i],vec[u][i-1]) ];
ct+=s[ vec[u][i-1] ];
que.push(make_pair(ct,w)),sg+=w;
}
ct=0;
int x=0;
while(!que.empty())//中位数
{
ct+=que.top().second;
if(ct>sg/2) {x=que.top().first;break;}
que.pop();
}
ct=0;
ans+=abs(ct-x)*mp[make_pair(vec[u][0],vec[u][cnt-1])];
for(int i=1;i<cnt;i++)
{
int w=mp[ make_pair(vec[u][i],vec[u][i-1]) ];
ct+=s[ vec[u][i-1] ];
ans+=w*abs(x-ct);
}
s[f[u]]=sum;
}
void dfs1(int u,int fa)
{
f[u]=fa;
for(int i=trhead[u];i;i=tred[i].nxt)
{
int v=tred[i].to;
if(v==fa) continue;
dfs1(v,u);
}
} signed main()
{
scanf("%lld%lld",&n,&m);
for(int i=1;i<=n;i++) scanf("%lld",&s[i]),pj+=s[i];
pj/=n;
for(int i=1;i<=n;i++) s[i]=s[i]-pj;
for(int i=1;i<=m;i++)
{
int x,y,z;
scanf("%lld%lld%lld",&x,&y,&z);
add(tot,head,edge,x,y);
add(tot,head,edge,y,x);
mp[make_pair(x,y)]=z;
mp[make_pair(y,x)]=z;
}
tx=n; tarjin(1);
dfs1(n,0);//答案是在计算过程中统计的,所以出发点设为圆点更方便统计
dfs2(n); printf("%lld",ans);
}

2023NOIP A层联测16 T3 货物运输的更多相关文章

  1. 【LCA&倍增】货物运输 @upcexam5909

    时间限制: 1 Sec 内存限制: 128 MB 题目描述 在一片苍茫的大海上,有n座岛屿,岛屿与岛屿之间由桥梁连接,所有的岛屿刚好被桥梁连接成一个树形结构,即共n-1架桥梁,且从任何一座岛屿出发都能 ...

  2. HDU 5699 货物运输 二分

    货物运输 题目连接: http://acm.hdu.edu.cn/showproblem.php?pid=5699 Description 公元2222年,l国发生了一场战争. 小Y负责领导工人运输物 ...

  3. Django自学计划之集装箱货物运输物流仓储一站式ERP系统

    业余开始学习时间:2018年1月 业余学习时间段:每天下班晚饭后时间+无事的星期六和星期天+上班时的空闲时间 自学目标: 1.我们要用管理的思维来写我们的系统! 2.我们要用我们的ERP系统帮助中小集 ...

  4. 【NOIP 2015 DAY2 T3】 运输计划 (树链剖分-LCA)

    题目背景 公元 2044 年,人类进入了宇宙纪元. 题目描述 L 国有 n 个星球,还有 n-1 条双向航道,每条航道建立在两个星球之间,这 n-1 条航道连通了 L 国的所有星球. 小 P 掌管一家 ...

  5. [51nod1671]货物运输

    公元2222年,l国发生了一场战争. 小Y负责领导工人运输物资. 其中有m种物资的运输方案,每种运输方案形如li,ri.表示存在一种货物从li运到ri. 这里有n个城市,第i个城市与第i+1个城市相连 ...

  6. NOIP2013 D1 T3 货车运输

    好吧,遇上这种题,作为蒟蒻的我第一个想到的就是怎么打暴力,然而暴力都打不好QAQ!!!于是只能等教练讲解以后,然后在大犇的指导下终于做出来了. 对了,,好像还,没上题....: 题目描述 A 国有 n ...

  7. NOIP2013 DAY2 T3火车运输

    传送门 题目描述 A 国有 n 座城市,编号从 1 到 n,城市之间有 m 条双向道路.每一条道路对车辆都有重量限制,简称限重.现在有 q 辆货车在运输货物, 司机们想知道每辆车在不超过车辆限重的情况 ...

  8. 货物运输 51Nod - 1671

    公元2222年,l国发生了一场战争. 小Y负责领导工人运输物资. 其中有m种物资的运输方案,每种运输方案形如li,ri.表示存在一种货物从li运到ri. 这里有n个城市,第i个城市与第i+1个城市相连 ...

  9. 51nod1671【货物运输】

    开始天真的我以为这道题和运输计划是一样的套路.于是写了一发,debug后发现过了第一个点,十分开心的交了一发,结果只过了第一个点.后来发现这个并不是一样的,因为修建黑洞之后路径法变了,而运输计划没有( ...

  10. @CSP模拟2019.10.16 - T3@ 垃圾分类

    目录 @description@ @solution@ @accepted code@ @details@ @description@ 为了保护环境,p6pou建设了一个垃圾分类器. 垃圾分类器是一个 ...

随机推荐

  1. 树莓派CM4(四):树莓派镜像替换内核

    树莓派镜像替换内核 1. 为什么要替换内核 树莓派官方提供的镜像中,自带的内核版本为6.6.31 然而github上提供的内核源码为6.6.40,有些微差别 此外,后续很有可能进行内核裁剪定制等工作, ...

  2. Kubernetes-14:持久化存储PV、PVC和StatefulSet介绍及使用

    PV.PVC简介 PersistentVolume(PV) 是由管理员设置的存储,它是集群的一部分,就像节点是集群中的资源一样,PV也是集群中的资源.PV是Volume之类的卷插件,但具有独立于使用P ...

  3. 【YashanDB知识库】共享集群YAC换IP

    [标题]共享集群YAC换IP [需求分类]安装部署,配置变更 [关键字]安装部署,更换IP,运维,配置变更,高可用,YAC [需求描述]客户需要将已经部署的YAC集群更换IP,从测试网段切换生产网段 ...

  4. RedisCluster集群架构原理与通信原理

    redis 参考目录: 生产级Redis 高并发分布式锁实战1:高并发分布式锁如何实现 https://www.cnblogs.com/yizhiamumu/p/16556153.html 生产级Re ...

  5. c++实现几种常见排序算法

    一.快速排序 int getPivot(vector<int>& arr, int left, int right){ int tmp = arr[left]; while(lef ...

  6. AGC007F 题解

    题意 给定两个长为 \(n\) 的字符串 \(S, T\),求最少进行多少次操作才能使 \(S = T\). 一次操作定义为:对于 \(i = 1, 2, .. n\),令第 \(i\) 位为操作后的 ...

  7. ASP.NET Core Library – HtmlSanitizer

    介绍 要输出 Raw HTML 最好是先消毒一下. 使用 Library 就可以了. 参考 Github – mganss / HtmlSanitizer 安装 nuget dotnet add pa ...

  8. DQL—查询操作

    一.查询语法 select 字段列表 from 表名列表 where 条件列表 group by 分组列表 having 分组后条件 order by 排序字段 limit 分页限定 (提供一个表来操 ...

  9. SpringMVC —— 日期类型参数传递

    日期类型参数传递    相关注解    类型转换器   

  10. CF708C Centroids [树形DP,换根DP]

    Description 给定一棵树. 至多进行一次操作:删去一条边,连接一条新边,保证操作完后仍是树. 问每个点在进行操作后是否可以成为树的重心. Solution 性质\(1\):若一个点不是树的重 ...