题解

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

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

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

重标号让代码显得好难看啊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. Codeforces Round #426 (Div. 1) B The Bakery (线段树+dp)

    B. The Bakery time limit per test 2.5 seconds memory limit per test 256 megabytes input standard inp ...

  2. 异步查询json传日期格式到前台,变成了时间戳的格式

    问题: 使用mybatis 查询mysql数据库,其中一个日期格式的字段,由异步查询使用 json传递到前台,变成了时间戳,而不是日期格式了.如何使查询出的日期展示成日期格式呢 解决办法: 1.尝试使 ...

  3. 【题解】 bzoj1190: [HNOI2007]梦幻岛宝珠 (动态规划)

    bzoj1190,懒得复制,戳我戳我 Solution: 这道题其实是一个背包(分组背包),但是由于数字比较大,就要重新构造dp式子.啃了三天才懂. \(dp[i][j]\)表示背包容积为\(j*2^ ...

  4. 解题:九省联考2018 IIIDX

    题面 我当时在考场上划水的时候好像乱搞搞了20pts,然后发现一堆同届的都写了55pts的贪心=.=??? 那就先说那55pts的贪心吧,这个现在看起来还是非常显然的,就是按题意来每一块是分属一个点的 ...

  5. CentOS 7 系统root用户忘记密码的重置方法

    在一台服务器我们忘记了root的账号或者root账号错误怎么办,我们只有进入到内核里面去修改,具体的操作如下: 1.进入内核 在开机的时候出现下图的界面时 按e键进入内核入下图 2.进入单用户模式 在 ...

  6. 质数——1到n遍历法

    一.从1至N全部遍历,当这个数只能被1和n整除它就是素数. /** * 打印自然数n以内的素数 */ public void printPrime(int n){ //是否为质数 boolean is ...

  7. 手机安全卫士-——Splash总结

    1.在AndroidManifest.xml文件的application中配置,应用的主题:不带标题的主题 android:theme="@android:style/Theme.Black ...

  8. 从url到页面加载浏览器做了什么?

    从输入url到页面加载发生了什么?1.DNS解析DNS解析是一个递归查询的过程.DNS解析的过程就是寻找哪台机器上有你需要资源的过程,当你在浏览器中输入一个地址时,www.baidu.com.其实不是 ...

  9. Git与GitHub学习笔记(二)提交的一些笔记

    1.合并分支的使用一定要切换到master分支上去合并:git merge company2.切换分支的时候一定要提交干净本地分支的代码,才可以切换分支,否则提示错误信息: 3.这时候我们做的就是提交 ...

  10. html js点击按钮滚动跳转定位到页面指定位置(DIV)的方法代码

    一:通过html锚点实现滚动定位到页面指定位置(DIV):    如果我们要点击实现跳转的地方是一个html锚点,也就是点击一个A标签超链接实现跳转,可以把A标签的href属性直接指向跳转指定位置的d ...