您的位置:首页 > 其它

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,呵呵,为自己鼓掌: )
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: