公路建设(Road.exe, 1s, 64M)
【问题描述】
A国是一个新兴的国家,有N个城市,分别编号为1,2.3…N。政府想大搞公路建设,提供了优惠政策:对于每一个投资方案的预计总费用,政府负担50%,并且允许投资的公司对过往的汽车收取连续5年的养路费。世界各地的大公司纷纷投资,并提出了自己的建设方案,他们的投资方案包括这些内容:公路连接的两座城市的编号,预计的总费用(假设他们的预计总师准确的)。你作为A国公路规划局的总工程师,有权利决定每一个方案是否接受。但是政府给你的要求是:
1)要保证各个城市之间都有公路直接或间接相连。
2)因为是新兴国家,政府的经济实力还不强。政府希望负担最少的费用。
因为大公司并不是同时提出方案,政府希望每接到一个方案,就可以知道当前需要负担的最小费用和接受的投资方案,以便随时开工。关于你给投资公司的回复可以等到开工以后再给。
注意:A国一开始是没有公路的。
【数据说明】A国的城市数目N<=500,投资的方案总数M<=2000。
【输入】输入文件名:Road.in
第1行有两个数字:N、M
第2行到第M+1行给出了各个投资方案,第i行的方案编号为i-1
编号小的方案先接到,一个方案占一行,每行有3个数字,分别是连接的两个城市编号a、b,和投资的预计总费用cost。
【输出】输出文件名:Road.out
输出文件共有M行。
每一行的第一个数字是当前政府需要负担的最少费用(保留1位小数),后面是X个数字,表示当前政府接受的方案的编号,不要求从小到大排列。但如果此时接受的所有投资方案不能保证政府的第一条要求,那么这一行只有一个数字0
【样例】
Road.in |
Road.out |
3 5 1 2 4 1 3 4 2 3 4 1 3 2 1 2 2 |
0 4.00 1 2 4.00 1 2 3.00 1 4 2.00 4 5 |
我的思路没有错误,在线算法,动态维护一个小根堆,然后用kruskal。很简单的一道题。但是WA0,因为完全弄错堆了,取堆中的值的时候,我是从1到m按顺序取的。但是删除才是堆的基本操作之一。。。因此可见基础代码必须要背呀。
为了维护堆的完整性,我另外开了一个临时堆,专门用来删除用。不过王哥介绍了一种方法,不用开临时堆,删除之后,留下内存中最后一段不动,要恢复就向上调整。
只是不知为何用了堆还比别人的慢很多。
//#include <iostream>
//using std::cout;
//using std::cin;
#include <cstdio>
struct ftv
{
longi;
longf;
longt;
doublev;
};
const long oo = 0x7fff0000;
long fa[3002];
ftv h[3002];
ftv h2[3002];
bool used[3002];
long size = 0;
long size2=