2075 Tangled in Cables 解题报告
2008-12-21 10:25
176 查看
AccecptTime: 2008-12-21 10:23:25Language: C++Memory: 328KTime: 0MSErrors: 5 WAAlgorithm: Kruskal + sort + bsearch
#include <stdio.h>
#include <stdlib.h>
#include <algorithm>
#include <iostream>
using namespace std;
// 储存电缆的长度,用名字对应的id来进行记录
typedef struct Cable {
int u;
int v;
double len;
bool operator() (Cable a,Cable b) {
return (a.len < b.len);
}
}Cable;
Cable cable[250000];
// 将名字和序号对应起来
typedef struct Name {
char name[25];
int id;
bool operator() (Name a,Name b) {
if(strcmp(a.name,b.name) < 0)
return true;
else
return false;
}
}Name;
Name name[5000];
int parent[5000];
//用于bsearch的比较函数
int compare(const void* a,const void* b)
{
return strcmp((char *)a,((Name*)b)->name);
}
// 并查集的寻找父节点
int Find(int x)
{
if(parent[x] >= 0) {
parent[x] = Find(parent[x]);
return parent[x];
}
else
return x;
}
// 将两个集合并在一起,将层次少的并入层次多的
void Union(int x,int y)
{
x = Find(x);
y = Find(y);
if( x == y)
return ;
if( parent[x] < parent[y])
parent[y] = x;
else
if(parent[x] == parent[y]) {
parent[y] = x;
parent[x]--;
}
else
parent[y] = x;
}
int main()
{
double sum;
int n,m;
Name *position;
char s1[25],s2[25];
double lenght;
cin >> sum;
cin >> n;
//对parent进行初始化,用parent = 负数来表示自己为父节点
//并用parent的绝对值来表示它的层次
memset(parent,-1,n * sizeof(int));
for(int i = 0; i < n; i++)
cin >> name[i].name;
//将名字进行排序并与id对上号
sort(name,name + n,Name());
for(int i = 0; i < n; i++)
name[i].id = i;
//读入电缆信息
cin >> m;
for(int i = 0; i < m; i++) {
cin >> s1 >> s2 >> lenght;
position = (Name*)bsearch(s1,name,n,sizeof(Name),compare);
cable[i].u = position - name;
position = (Name*)bsearch(s2,name,n,sizeof(Name),compare);
cable[i].v = position - name;
cable[i].len = lenght;
}
// 对电缆进行排序以进行Kruskal
sort(cable,cable+m,Cable());
int count = 0,j = 0;
double needLen = 0.0;
while(true) {
if(Find(cable[j].u) != Find(cable[j].v)) {
Union(cable[j].u,cable[j].v);
needLen += cable[j].len;
count++;
j++;
}
else
j++;
if(j == m)
break;
}
//为了避免输入误差sum加了0.0001(不知道有用否...)
if( needLen > (sum+10e-4))
cout << "Not enough cable/n";
else
printf("Need %.1f miles of cable/n",needLen);
return 0;
}
这道题不是一道很难的题目,但是考察的知识点比较多,有bsearch,sort,Kruskal,其中我对Kruskal中的并查集进行路径压缩。一开始由于不熟悉用父节点parent的绝对值来表示层次,wa了5次。幸好自己终于学会沉下气来找到了bug,呵呵,为自己鼓掌: )
#include <stdio.h>
#include <stdlib.h>
#include <algorithm>
#include <iostream>
using namespace std;
// 储存电缆的长度,用名字对应的id来进行记录
typedef struct Cable {
int u;
int v;
double len;
bool operator() (Cable a,Cable b) {
return (a.len < b.len);
}
}Cable;
Cable cable[250000];
// 将名字和序号对应起来
typedef struct Name {
char name[25];
int id;
bool operator() (Name a,Name b) {
if(strcmp(a.name,b.name) < 0)
return true;
else
return false;
}
}Name;
Name name[5000];
int parent[5000];
//用于bsearch的比较函数
int compare(const void* a,const void* b)
{
return strcmp((char *)a,((Name*)b)->name);
}
// 并查集的寻找父节点
int Find(int x)
{
if(parent[x] >= 0) {
parent[x] = Find(parent[x]);
return parent[x];
}
else
return x;
}
// 将两个集合并在一起,将层次少的并入层次多的
void Union(int x,int y)
{
x = Find(x);
y = Find(y);
if( x == y)
return ;
if( parent[x] < parent[y])
parent[y] = x;
else
if(parent[x] == parent[y]) {
parent[y] = x;
parent[x]--;
}
else
parent[y] = x;
}
int main()
{
double sum;
int n,m;
Name *position;
char s1[25],s2[25];
double lenght;
cin >> sum;
cin >> n;
//对parent进行初始化,用parent = 负数来表示自己为父节点
//并用parent的绝对值来表示它的层次
memset(parent,-1,n * sizeof(int));
for(int i = 0; i < n; i++)
cin >> name[i].name;
//将名字进行排序并与id对上号
sort(name,name + n,Name());
for(int i = 0; i < n; i++)
name[i].id = i;
//读入电缆信息
cin >> m;
for(int i = 0; i < m; i++) {
cin >> s1 >> s2 >> lenght;
position = (Name*)bsearch(s1,name,n,sizeof(Name),compare);
cable[i].u = position - name;
position = (Name*)bsearch(s2,name,n,sizeof(Name),compare);
cable[i].v = position - name;
cable[i].len = lenght;
}
// 对电缆进行排序以进行Kruskal
sort(cable,cable+m,Cable());
int count = 0,j = 0;
double needLen = 0.0;
while(true) {
if(Find(cable[j].u) != Find(cable[j].v)) {
Union(cable[j].u,cable[j].v);
needLen += cable[j].len;
count++;
j++;
}
else
j++;
if(j == m)
break;
}
//为了避免输入误差sum加了0.0001(不知道有用否...)
if( needLen > (sum+10e-4))
cout << "Not enough cable/n";
else
printf("Need %.1f miles of cable/n",needLen);
return 0;
}
这道题不是一道很难的题目,但是考察的知识点比较多,有bsearch,sort,Kruskal,其中我对Kruskal中的并查集进行路径压缩。一开始由于不熟悉用父节点parent的绝对值来表示层次,wa了5次。幸好自己终于学会沉下气来找到了bug,呵呵,为自己鼓掌: )
相关文章推荐
- Pku acm 2075 Tangled in Cables数据结构题目解题报告(十一)最小生成树:prim算法&amp;amp;二叉查找树
- Pku acm 2075 Tangled in Cables数据结构题目解题报告(十一)最小生成树:prim算法&amp;amp;二叉查找树
- zoj 2326 || poj 2075 Tangled in Cables(MST)
- POJ 2075 Tangled in Cables
- POJ 2075 Tangled in Cables 最小生成树
- POJ 2075 Tangled in Cables 最小生成树
- POJ 2075 Tangled in Cables(最小生成树 kruscal)
- poj 2075 -- Tangled in Cables(最小生成树)
- POJ 2075:Tangled in Cables 【Prim】
- poj 2075 Tangled in Cables
- POJ 2075 Tangled in Cables (kruskal算法 MST + map)
- POJ 2075 Tangled in Cables (c++/java)
- POJ 2075 Tangled in Cables(最小生成树)
- codevs 2075 yh女朋友的危机 解题报告
- 百练 2075: Tangled in Cables
- 浙大ACM 2075 Ellipsoid Volume解题报告
- POJ 2075 Tangled in Cables (c++/java)
- poj 2075 Tangled in Cables【最小生成树+字符串处理】
- POJ 2075 Tangled in Cables
- POJ 2075 Tangled in Cables