SGU 323 Aviamachinations

最小生成树的经典题目.

http://acm.hust.edu.cn/vjudge/contest/view.action?cid=33862#problem/H

首先容易知道我们必须从小到大枚举航空公司,然后对该航空公司占有的边直接加入到生成树中,然后为了保证该生成树的边的权值总和最小,因此剩余的边只能从最小生成树的边中取,因此我们在预处理的时候需要求解一次最小生成树,保存最小生成树上的边的序号,最后我们从最小生成树中选边便只需要O(n)的复杂度.(PS:从最小生成树中一定包含了剩余的需要添加入新的生成树中的边,最小生成树的所有的边和已经加入的边这样的图是存在环的,从环上删除最小生成树的边总能得到我们要构造的生成树),最后我们便采用上述方法遍历所有的航空公司,取最优值,保存相应的信息即可...


#include <cmath>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;
const int MAXN = 2020;
const int MAXM = 200010;
const int INF  = 0x3f3f3f3f;

struct Edge
{
    int id, u, v, w, next;
    Edge() {}
    Edge(int t_id, int t_u, int t_v, int t_w, int t_next) : id(t_id), u(t_u), v(t_v), w(t_w), next(t_next) {}
    friend bool operator < (const Edge &e1, const Edge &e2)
    {
        return e1.w < e2.w;
    }
}edge1[MAXM], edge2[MAXM];

int head[MAXN], len, cnt;
int parent[MAXN], ans[MAXN];
int result[MAXN], tmp[MAXN];
int n, m, k, res, res_id, res_cnt;

void Init()
{
    len = 0;
    memset(head, -1, sizeof(head));
}

void addEdge(int u, int v, int w, int x, int id)
{
    edge2[len].u = u;
    edge2[len].v = v;
    edge2[len].w = w;
    edge2[len].id = id;
    edge2[len].next = head[x];
    head[x] = len++;
}

void init_set()
{
    memset(parent, -1, sizeof(parent));
}

int find_set(int x)
{
    return parent[x] < 0 ? x : parent[x] = find_set(parent[x]);
}

void union_set(int x, int y)
{
    int r1 = find_set(x), r2 = find_set(y);
    if(r1 != r2)
    {
        if(parent[r2] < parent[r1])
        {
            parent[r2] += parent[r1];
            parent[r1] = r2;
        }
        else
        {
            parent[r1] += parent[r2];
            parent[r2] = r1;
        }
    }
    return ;
}

void Kruskal()
{
    init_set();
    int num = 0; //int sum = 0;
    sort(edge1 + 1, edge1 + k + 1);
    for(int i = 1; i <= k; ++i)
    {
        int r1 = find_set(edge1[i].u), r2 = find_set(edge1[i].v);
        if(r1 != r2)
        {
            //sum += edge1[i].w;
            ans[++num] = i;  //注意这里的标号
            union_set(edge1[i].u, edge1[i].v);
        }
        if(num >= n-1) break;
    }
    //printf("Test:  %d\n", sum);
    /*
    for(int i = 1; i < n; ++i)
    {
        printf("%d ", ans[i]);
    }
    printf("\n");
    */
    return ;
}

void solve()
{
    res = INF, res_id = -1; res_cnt = 0;
    int sum, cnt;
    for(int i = 1; i <= m; ++i)
    {
        init_set();
        for(int j = head[i]; j != -1; j = edge2[j].next)
        {
            int u = edge2[j].u, v = edge2[j].v;
            if(find_set(u) != find_set(v))
                union_set(u, v);
        }
        sum = 0; cnt = 0;
        for(int j = 1; j < n; ++j)
        {
            int u = edge1[ans[j]].u, v = edge1[ans[j]].v;
            //printf("%d %d %d\n", u, v, edge1[ans[j]].w);
            if(find_set(u) != find_set(v))
            {
                sum += edge1[ans[j]].w;
                union_set(u, v);
                tmp[cnt++] = ans[j];
            }
        }
        if(res > sum)
        {
            res = sum; res_id = i; res_cnt = cnt;
            for(int j = 0; j < cnt; ++j)
            {
                result[j] = tmp[j];
            }
        }
    }
    printf("%d %d %d\n", res, res_id, res_cnt);
    sort(result, result + res_cnt);
    for(int i = 0; i < res_cnt; ++i)
    {
        if(i == 0)
            printf("%d", edge1[result[i]].id);
        else
            printf(" %d", edge1[result[i]].id);
    }
    printf("\n");
    return ;
}

int main()
{
    //freopen("aa.in", "r", stdin);

    int a, b, c, p;

    scanf("%d %d %d", &n, &m, &k);
    Init();
    for(int i = 1; i <= k; ++i)
    {
        scanf("%d %d %d %d", &a, &b, &c, &p);
        edge1[i].u = a, edge1[i].v = b, edge1[i].w = p, edge1[i].id = i;
        addEdge(a, b, p, c, i);
    }
    Kruskal();
    solve();
    return 0;
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
资源包主要包含以下内容: ASP项目源码:每个资源包中都包含完整的ASP项目源码,这些源码采用了经典的ASP技术开发,结构清晰、注释详细,帮助用户轻松理解整个项目的逻辑和实现方式。通过这些源码,用户可以学习到ASP的基本语法、服务器端脚本编写方法、数据库操作、用户权限管理等关键技术。 数据库设计文件:为了方便用户更好地理解系统的后台逻辑,每个项目中都附带了完整的数据库设计文件。这些文件通常包括数据库结构图、数据表设计文档,以及示例数据SQL脚本。用户可以通过这些文件快速搭建项目所需的数据库环境,并了解各个数据表之间的关系和作用。 详细的开发文档:每个资源包都附有详细的开发文档,文档内容包括项目背景介绍、功能模块说明、系统流程图、用户界面设计以及关键代码解析等。这些文档为用户提供了深入的学习材料,使得即便是从零开始的开发者也能逐步掌握项目开发的全过程。 项目演示与使用指南:为帮助用户更好地理解和使用这些ASP项目,每个资源包中都包含项目的演示文件和使用指南。演示文件通常以视频或图文形式展示项目的主要功能和操作流程,使用指南则详细说明了如何配置开发环境、部署项目以及常见问题的解决方法。 毕业设计参考:对于正在准备毕业设计的学生来说,这些资源包是绝佳的参考材料。每个项目不仅功能完善、结构清晰,还符合常见的毕业设计要求和标准。通过这些项目,学生可以学习到如何从零开始构建一个完整的Web系统,并积累丰富的项目经验。
资源包主要包含以下内容: ASP项目源码:每个资源包中都包含完整的ASP项目源码,这些源码采用了经典的ASP技术开发,结构清晰、注释详细,帮助用户轻松理解整个项目的逻辑和实现方式。通过这些源码,用户可以学习到ASP的基本语法、服务器端脚本编写方法、数据库操作、用户权限管理等关键技术。 数据库设计文件:为了方便用户更好地理解系统的后台逻辑,每个项目中都附带了完整的数据库设计文件。这些文件通常包括数据库结构图、数据表设计文档,以及示例数据SQL脚本。用户可以通过这些文件快速搭建项目所需的数据库环境,并了解各个数据表之间的关系和作用。 详细的开发文档:每个资源包都附有详细的开发文档,文档内容包括项目背景介绍、功能模块说明、系统流程图、用户界面设计以及关键代码解析等。这些文档为用户提供了深入的学习材料,使得即便是从零开始的开发者也能逐步掌握项目开发的全过程。 项目演示与使用指南:为帮助用户更好地理解和使用这些ASP项目,每个资源包中都包含项目的演示文件和使用指南。演示文件通常以视频或图文形式展示项目的主要功能和操作流程,使用指南则详细说明了如何配置开发环境、部署项目以及常见问题的解决方法。 毕业设计参考:对于正在准备毕业设计的学生来说,这些资源包是绝佳的参考材料。每个项目不仅功能完善、结构清晰,还符合常见的毕业设计要求和标准。通过这些项目,学生可以学习到如何从零开始构建一个完整的Web系统,并积累丰富的项目经验。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值