题解

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

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

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

重标号让代码显得好难看啊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. emacs 图解

    emacs 图解 =================== End

  2. MT【76】直线系

    解答 :答案是3,4.

  3. 学习Spring Boot:(十六)使用Shiro与JWT 实现认证服务

    前言 需要把Web应用做成无状态的,即服务器端无状态,就是说服务器端不会存储像会话这种东西,而是每次请求时access_token进行资源访问.这里我们将使用 JWT 1,基于散列的消息认证码,使用一 ...

  4. 【BZOJ1296】[SCOI2009]粉刷匠(动态规划)

    [BZOJ1296][SCOI2009]粉刷匠(动态规划) 题面 BZOJ 洛谷 题解 一眼题吧. 对于每个串做一次\(dp\),求出这个串刷若干次次能够达到的最大值,然后背包合并所有的结果即可. # ...

  5. 【BZOJ1293】[SCOI2009]生日礼物(单调队列)

    [BZOJ1293][SCOI2009]生日礼物(单调队列) 题面 BZOJ 洛谷 题解 离散之后随便拿单调队列维护一下就好了. #include<iostream> #include&l ...

  6. BZOJ 2039 [2009国家集训队]employ人员雇佣 网络流

    链接 BZOJ 2039 题解 这题建图好神,自己瞎搞了半天,最后不得不求教了企鹅学长的博客,,,,发现建图太神了!! s向每个人连sum(e[i][x]) 的边,每个人向T连a[i]的边.两两人之间 ...

  7. GDKOI2018发烧记

    偏远小渔村NOIP螺旋升天选手又一次来到了广州参加GDKOI...金实的初三爷们也来啦?要被碾啦T T Day 0 跟HR Lao爷拼(biao)车到了高铁站,上了高铁居然没有颓颓颓吃吃吃(雾),安心 ...

  8. IIS并发连接数及性能优化

    如果要查看IIS连接数,最简单方便的方法是通过“网站统计”来查看,“网站统计”的当前在线人数可以认为是当前IIS连接数.然而,“网站统计”的当前在线人数统计时间较长,一般为10分钟或15分钟,再加上统 ...

  9. activiti 用户手册中 10分钟 小例子 简单代码搭建 及 其中的 各种坑

    看mossle的 5.16 用户手册中的  快速起步:10分钟教程 想自己跑一下,虽然官方文档已经写的非常详细了,但是实际操作中还是遇到各种坑,这里记录下来. 首先官网下载最新的 5版本 full G ...

  10. UML类图学习笔记

    http://note.youdao.com/noteshare?id=d5af220db7081dda73511fcb7b4da390