题解

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

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

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

重标号让代码显得好难看啊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. 【题解】 bzoj1875: [SDOI2009]HH去散步 (动态规划+矩阵乘法)

    bzoj1875,懒得复制,戳我戳我 Solution: 看到这道题,看的出是个dp,每个点\(t\)时刻到达的方案数等于\(t-1\)到连过来的点方案数之和 但又因为题目有要求不能走一样的边回去不是 ...

  2. 【BZOJ1044】[HAOI2008]木棍分割(动态规划,贪心)

    [BZOJ1044][HAOI2008]木棍分割(动态规划,贪心) 题面 BZOJ 洛谷 题解 第一问随便二分一下就好了,贪心\(check\)正确性显然. 第二问随便前缀和+单调队列优化一下\(dp ...

  3. 洛谷 P4841 城市规划 解题报告

    P4841 城市规划 题意 n个有标号点的简单(无重边无自环)无向连通图数目. 输入输出格式 输入格式: 仅一行一个整数\(n(\le 130000)\) 输出格式: 仅一行一个整数, 为方案数 \( ...

  4. 前端学习 -- Css -- 样式的继承

    像儿子可以继承父亲的遗产一样,在CSS中,祖先元素上的样式,也会被他的后代元素所继承, 利用继承,可以将一些基本的样式设置给祖先元素,这样所有的后代元素将会自动继承这些样式. 但是并不是所有的样式都会 ...

  5. java基础基础总结----- RunTime

  6. JVM总结(一):概述--JVM运行时数据区

    大三下,趁着寒假重温一遍JVM,准备在一个系列来总价一下学习JVM的整个过程.争取在接下来的一个星期内更新完这一个系列,然后回家过年. JVM运行时数据区 线程私有的数据区 程序计数器 虚拟机栈 本地 ...

  7. js 正则之 检测素数

    相信很多人应该看过这篇文章,我第一次看到的时候是11年的样子,那时候学vbs的时候看过这个问题.原文<检查素数的正则表达式>,在文章里已经解释了他是怎么判断的,我就不啰嗦了.我们来说说 j ...

  8. Spring Tool Suite 创建 SpringMVC+Maven 项目(一)!

    使用Spring Tool Suite 创建 SpringMVC Web 项目,使用Maven来管理依赖! 首先对环境进行必要的配置 1. 配置必要的Java JDK版本! (菜单栏-窗口-首选项.) ...

  9. 【转】在Mac OS X 10.8中配置Apache + PHP + MySQL

    CHENYILONG Blog 在Mac OS X 10.8中配置Apache + PHP + MySQL 在Mac OS X 10.8中配置Apache+PHP+MySQL的内容包括: 配置Apac ...

  10. iOS手势UIGestureRecognizer的使用及手势冲突的解决办法【转】

    转自:iOS开发中的手势体系——UIGestureRecognizer分析及其子类的使用 关于手势的一篇很好的帖子,转载过来免得丢失.你可能最感兴趣的是手势间的互斥处理,那么就搜索 4.手势间的互斥处 ...