【BZOJ】4349: 最小树形图
题解
我们只考虑给每个点买一个,之后每个点就可以用最低价格买了
根据最小树形图的算法,就是不断给每个点入度的边找一条最小的
如果构成了树形图就退出,否则把形成了环的点缩成一个点,加上环的权值,然后把指向环中点的弧变成弧长减去环中指向该点的弧的长度
重标号让代码显得好难看啊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: 最小树形图的更多相关文章
- 【刷题】BZOJ 4349 最小树形图
Description 小C现在正要攻打科学馆腹地------计算机第三机房.而信息组的同学们已经建好了一座座堡垒,准备迎战.小C作为一种高度智慧的可怕生物,早已对同学们的信息了如指掌. 攻打每一个人 ...
- bzoj 4349 最小树形图——朱刘算法
题目:https://www.lydsy.com/JudgeOnline/problem.php?id=4349. 学习博客:http://www.cnblogs.com/xzxl/p/7243466 ...
- bzoj2260: 商店购物 && 4349: 最小树形图
Description Grant是一个个体户老板,他经营的小店因为其丰富的优惠方案深受附近居民的青睐,生意红火.小店的优惠方案十分简单有趣.Grant规定:在一次消费过程中,如果您在本店购买了精制油 ...
- bzoj2260: 商店购物&&4349: 最小树形图
最小树形图问题啊 最小树形图是撒哩,就是给你一个有向图,确定一个根,要你到达所有点,那棵最短路径树的总边权 做这个用的是朱(jv)刘(lao)算法. 首先假如有多个联通块就无解啦 对应每个点(除了根) ...
- 【Bzoj2260】【Bzoj4349】商店购物 & 最小树形图
目录 List Bzoj 2260 商店购物 Description Input Output Sample Input Sample Output Bzoj 4349 最小树形图 Descripti ...
- 【BZOJ 2753】 2753: [SCOI2012]滑雪与时间胶囊 (分层最小树形图,MST)
2753: [SCOI2012]滑雪与时间胶囊 Time Limit: 50 Sec Memory Limit: 128 MBSubmit: 2457 Solved: 859 Descriptio ...
- BZOJ 2260 商店购物(最小树形图)
不会最小树形图的出门左转 其实如果确定每种商品第一件的购买顺序,那么剩下的商品肯定是以最优惠价格购买的. 如何确定各种商品第一件购买时的最小价值呢? 考虑如果购买了\(a_i\)这种商品,那么就能以\ ...
- 【最小树形图(奇怪的kruskal)】【SCOI 2012】【bzoj 2753】滑雪与时间胶囊
2753: [SCOI2012]滑雪与时间胶囊 Time Limit: 50 Sec Memory Limit: 128 MB Submit: 1621 Solved: 570 Description ...
- [JSOI2008]小店购物 & bzoj4349:最小树形图 最小树形图
---题面(洛谷)--- ---题面(bzoj)--- 其实是同一道题,,,样例都一模一样 题解: 一开始看想了好久,,,还想到了最短路和最小生成树,,然而写的时候才意识到最小生成树应该要用无向边 其 ...
随机推荐
- Day25-博客系统
1. 搭建环境请参考:http://www.cnblogs.com/momo8238/p/7508677.html 2.创建3张表备用 models.py from django.db import ...
- Lisp之根源 --- 保罗格雷厄姆
Lisp之根源 --- 保罗格雷厄姆 来源 http://daiyuwen.freeshell.org/gb/rol/roots_of_lisp.html 约翰麦卡锡于1960年发表了一篇非凡的论文, ...
- 架构师成长之路1.1-系统监控工具htop
点击返回架构师成长之路 架构师成长之路1.1-系统监控工具htop htop 是Linux系统中的一个互动的进程查看器,一个文本模式的应用程序(在控制台或者X终端中),需要ncurses. 与Linu ...
- Mysql(四)正则表达式
一.正则表达式 1.使用like可以进行不确定的查询(模糊查询),然而,模糊 查询的功能有限,当需要进行更加复杂的模式匹配时,可以 使用正则表达式来完成. 2.正则表达式可以对指定的字符串与模式之间执 ...
- linux中eth0原何变成了eth1
Linux的网卡由eth0变成了eth1,如何修复使用wmware安装了linux,安装成功后,使用的网卡是eth0,没有eth1.但是用过一段时间后,不知道为什么eth0无法使用,系统却自动生成了e ...
- John:How JavaScript Timers Work
John大神的bolg链接:http://ejohn.org/blog/how-javascript-timers-work/ JavaScript中的定时器经常表现的跟我们想象的不同,我们用三个函数 ...
- python教程2:list和tuple
list和tuple都是数组,区别在于list可以随意增删改查,而tuple在赋值了之后只能查看了,所以tuple是比较安全的相对于list来说 list 定义一个list数组,名字就叫list,可以 ...
- 最长回文子串问题-Manacher算法
转:http://blog.csdn.net/dyx404514/article/details/42061017 Manacher算法 算法总结第三弹 manacher算法,前面讲了两个字符串相算法 ...
- scale.fix.js
无意间在一个网站上看到的,本来是对另一个效果感兴趣的,结果看到这个放开来的js就读了一下. var metas = document.getElementsByTagName('meta'); var ...
- BAT及各大互联网公司2014前端笔试面试题--Html,Css篇(昨天有个群友表示写的简单了点,然后我无情的把他的抄了一遍)
某个群友 http://www.cnblogs.com/coco1s/ 很多面试题是我自己面试BAT亲身经历碰到的.整理分享出来希望更多的前端er共同进步吧,不仅适用于求职者,对于巩固复习前端基础 ...