题解

我们只考虑给每个点买一个,之后每个点就可以用最低价格买了

根据最小树形图的算法,就是不断给每个点入度的边找一条最小的

如果构成了树形图就退出,否则把形成了环的点缩成一个点,加上环的权值,然后把指向环中点的弧变成弧长减去环中指向该点的弧的长度

重标号让代码显得好难看啊QAQ

代码

#include <bits/stdc++.h>
#define fi first
#define se second
#define pii pair<int,int>
#define pdi pair<db,int>
#define mp make_pair
#define pb push_back
#define enter putchar('\n')
#define space putchar(' ')
#define eps 1e-8
#define mo 974711
#define MAXN 1000005
//#define ivorysi
using namespace std;
typedef long long int64;
typedef double db;
template<class T>
void read(T &res) {
res = 0;char c = getchar();T f = 1;
while(c < '0' || c > '9') {
if(c == '-') f = -1;
c = getchar();
}
while(c >= '0' && c <= '9') {
res = res * 10 + c - '0';
c = getchar();
}
res *= f;
}
template<class T>
void out(T x) {
if(x < 0) {x = -x;putchar('-');}
if(x >= 10) {
out(x / 10);
}
putchar('0' + x % 10);
}
int N,num[55],Ncnt,id[55];
db g[55][55],f[55][55],ans,val[55],tmp,minv[55];
int h[55][55],sta[55],top,low[55],dfn[55],idx,instack[55],tot;
int que[55],qr;
void Tarjan(int u) {
low[u] = dfn[u] = ++idx;
sta[++top] = u;
instack[u] = 1;
for(int v = 1 ; v < Ncnt ; ++v) {
if(h[u][v]) {
if(!dfn[v]) {Tarjan(v);low[u] = min(low[u],low[v]);}
else if(instack[v] == 1) {low[u] = min(low[u],dfn[v]);}
}
}
if(low[u] >= dfn[u]) {
++tot;
qr = 0;
while(1) {
int x = sta[top--];
id[x] = tot;
que[++qr] = x;
instack[x] = 2;
if(x == u) break;
}
if(qr == 1) {val[que[1]] = 0;}
else {
for(int i = 1 ; i <= qr ; ++i) ans += val[que[i]];
}
}
}
void shortest_arborescence() {
while(1) {
memset(h,0,sizeof(h));
tmp = 0.0;
for(int i = 1 ; i < Ncnt ; ++i) {
int t = Ncnt;
for(int j = 1 ; j < Ncnt ; ++j) {
if(g[j][i] < g[t][i]) t = j;
}
h[t][i] = 1;
val[i] = g[t][i];
tmp += val[i];
}
memset(dfn,0,sizeof(dfn));
memset(low,0,sizeof(low));
memset(instack,0,sizeof(instack));
tot = 0;idx = 0;top = 0;
for(int i = 1 ; i < Ncnt ; ++i) {
if(!dfn[i]) Tarjan(i);
}
id[Ncnt] = ++tot;
if(tot == Ncnt) {
ans += tmp;
break;
}
for(int i = 1 ; i <= tot ; ++i) {
for(int j = 1 ; j <= tot ; ++j) {
f[i][j] = 1000000000.0;
}
}
for(int i = 1 ; i <= Ncnt ; ++i) {
for(int j = 1 ; j <= Ncnt ; ++j) {
if(id[i] == id[j]) continue;
if(g[i][j] < 1000000000)
f[id[i]][id[j]] = min(f[id[i]][id[j]],g[i][j] - val[j]);
}
}
Ncnt = tot;
memcpy(g,f,sizeof(f));
}
printf("%.2lf\n",ans);
}
void Solve() {
read(N);
for(int i = 1 ; i <= N + 1 ; ++i) {
for(int j = 1 ; j <= N + 1 ; ++j) {
g[i][j] = 1000000000.0;
}
}
for(int i = 1 ; i <= N ; ++i) {
scanf("%lf",&minv[i]);
read(num[i]);
g[N + 1][i] = minv[i];
if(num[i]) id[i] = ++Ncnt;
}
id[N + 1] = ++Ncnt;
int k,A,B;db c;
read(k);
for(int i = 1 ; i <= k ; ++i) {
read(A);read(B);scanf("%lf",&c);
g[A][B] = min(g[A][B],c);
if(num[A]) minv[B] = min(minv[B],c);
}
for(int i = 1 ; i <= N ; ++i) {
if(num[i]) ans += minv[i] * (num[i] - 1);
}
for(int i = 1 ; i <= Ncnt ; ++i) {
for(int j = 1 ; j <= Ncnt ; ++j) {
f[i][j] = 1000000000.0;
}
}
for(int i = 1 ; i <= N + 1; ++i) {
if(!id[i]) continue;
for(int j = 1 ; j <= N + 1; ++j) {
if(!id[j]) continue;
f[id[i]][id[j]] = g[i][j];
}
}
memcpy(g,f,sizeof(g));
shortest_arborescence();
}
int main() {
#ifdef ivorysi
freopen("f1.in","r",stdin);
#endif
Solve();
return 0;
}

【BZOJ】4349: 最小树形图的更多相关文章

  1. 【刷题】BZOJ 4349 最小树形图

    Description 小C现在正要攻打科学馆腹地------计算机第三机房.而信息组的同学们已经建好了一座座堡垒,准备迎战.小C作为一种高度智慧的可怕生物,早已对同学们的信息了如指掌. 攻打每一个人 ...

  2. bzoj 4349 最小树形图——朱刘算法

    题目:https://www.lydsy.com/JudgeOnline/problem.php?id=4349. 学习博客:http://www.cnblogs.com/xzxl/p/7243466 ...

  3. bzoj2260: 商店购物 && 4349: 最小树形图

    Description Grant是一个个体户老板,他经营的小店因为其丰富的优惠方案深受附近居民的青睐,生意红火.小店的优惠方案十分简单有趣.Grant规定:在一次消费过程中,如果您在本店购买了精制油 ...

  4. bzoj2260: 商店购物&&4349: 最小树形图

    最小树形图问题啊 最小树形图是撒哩,就是给你一个有向图,确定一个根,要你到达所有点,那棵最短路径树的总边权 做这个用的是朱(jv)刘(lao)算法. 首先假如有多个联通块就无解啦 对应每个点(除了根) ...

  5. 【Bzoj2260】【Bzoj4349】商店购物 & 最小树形图

    目录 List Bzoj 2260 商店购物 Description Input Output Sample Input Sample Output Bzoj 4349 最小树形图 Descripti ...

  6. 【BZOJ 2753】 2753: [SCOI2012]滑雪与时间胶囊 (分层最小树形图,MST)

    2753: [SCOI2012]滑雪与时间胶囊 Time Limit: 50 Sec  Memory Limit: 128 MBSubmit: 2457  Solved: 859 Descriptio ...

  7. BZOJ 2260 商店购物(最小树形图)

    不会最小树形图的出门左转 其实如果确定每种商品第一件的购买顺序,那么剩下的商品肯定是以最优惠价格购买的. 如何确定各种商品第一件购买时的最小价值呢? 考虑如果购买了\(a_i\)这种商品,那么就能以\ ...

  8. 【最小树形图(奇怪的kruskal)】【SCOI 2012】【bzoj 2753】滑雪与时间胶囊

    2753: [SCOI2012]滑雪与时间胶囊 Time Limit: 50 Sec Memory Limit: 128 MB Submit: 1621 Solved: 570 Description ...

  9. [JSOI2008]小店购物 & bzoj4349:最小树形图 最小树形图

    ---题面(洛谷)--- ---题面(bzoj)--- 其实是同一道题,,,样例都一模一样 题解: 一开始看想了好久,,,还想到了最短路和最小生成树,,然而写的时候才意识到最小生成树应该要用无向边 其 ...

随机推荐

  1. Cuba项目从远程Git仓库下载步骤

    Cuba Studio 从Git远程仓库里下载代码,并且可以使用IDEA打开,需要注意的地方: 1.使用Git Gui克隆代码 也可以使用IDEA本身集成的Git下载,但是要保证:下载了项目以后,不能 ...

  2. javaee, javaweb和javase的区别以及各自的知识体系

    javaee, javaweb和javase的区别以及各自的知识体系 来源 https://blog.csdn.net/weixin_39297312/article/details/79454642 ...

  3. 【刷题】BZOJ 2001 [Hnoi2010]City 城市建设

    Description PS国是一个拥有诸多城市的大国,国王Louis为城市的交通建设可谓绞尽脑汁.Louis可以在某些城市之间修建道路,在不同的城市之间修建道路需要不同的花费.Louis希望建造最少 ...

  4. IO编程(3)-序列化

    序列化 在程序运行的过程中,所有的变量都是在内存中,比如,定义一个dict: d = dict(name='Bob', age=20, score=88) 可以随时修改变量,比如把name改成'Bil ...

  5. 本地如何连接虚拟机上的MySql

    今天在本地链接虚拟机上的MySql,然而链接失败了!甚是尴尬! 首先想一想是什么原因导致链接失败: 基础环境:在Linux上安装mysql 1.检查虚拟机IP在本地是否可以ping 通过 虚拟机IP: ...

  6. 如何构建 Redis 高可用架构?

    温国兵 民工哥技术之路 今天 1 .题记 Redis 是一个开源的使用 ANSI C 语言编写.支持网络.可基于内存亦可持久化的日志型.Key-Value 数据库,并提供多种语言的 API. 如今,互 ...

  7. IE条件注释判断

    相信大家都知道IE有专门的注释条件判断来引入一些css.js.html代码,但是语法有点拗口,记不住,下面我来做一下笔记: 正常的html注释: <!--注释注释注释注释...--> 注释 ...

  8. yolo详解

    文章<You Only Look Once: Unified, Real-Time Object Detection>提出方法下面简称YOLO. 目前,基于深度学习算法的一系列目标检测算法 ...

  9. openstack项目【day23】:虚拟化介绍

    本节内容 一 什么是虚拟化 二 为何要学习虚拟化 三 虚拟化技术主要分类(了解) 四 平台虚拟化技术又可以细分(了解) 一 什么是虚拟化 虚拟化说白了就是本来是一个完整的资源,切分或者说虚拟成多份,让 ...

  10. javascript鼠标拖拽的那些事情

    <html> <head> <title>javascript鼠标拖拽的那些事情</title> <meta http-equiv="C ...