题目链接: 传送门

Agri-Net

Time Limit: 1000MS     Memory Limit: 10000K

Description

Farmer John has been elected mayor of his town! One of his campaign promises was to bring internet connectivity to all farms in the area. He needs your help, of course.
Farmer John ordered a high speed connection for his farm and is going to share his connectivity with the other farmers. To minimize cost, he wants to lay the minimum amount of optical fiber to connect his farm to all the other farms.
Given a list of how much fiber it takes to connect each pair of farms, you must find the minimum amount of fiber needed to connect them all together. Each farm must connect to some other farm such that a packet can flow from any one farm to any other farm.
The distance between any two farms will not exceed 100,000.

Input

The input includes several cases. For each case, the first line contains the number of farms, N (3 <= N <= 100). The following lines contain the N x N conectivity matrix, where each element shows the distance from on farm to another. Logically, they are N lines of N space-separated integers. Physically, they are limited in length to 80 characters, so some lines continue onto others. Of course, the diagonal will be 0, since the distance from farm i to itself is not interesting for this problem.

Output

For each case, output a single integer length that is the sum of the minimum length of fiber required to connect the entire set of farms.

Sample Input

4
0 4 9 21
4 0 8 17
9 8 0 16
21 17 16 0

Sample Output

28

Prim算法O(V^2)

#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
const int INF = 0x3f3f3f3f;
const int MAX_V = 105;
int edge[MAX_V][MAX_V];
int dis[MAX_V];
bool vis[MAX_V];
int N;

int prim()
{
    memset(dis,INF,sizeof(dis));
    memset(vis,false,sizeof(vis));
    for (int i = 1;i <= N;i++)
    {
        dis[i] = edge[i][1];
    }
    dis[1] = 0;
    vis[1] = true;
    int sum = 0;
    for (int i = 1;i < N;i++)
    {
        int tmp = INF,pos;
        for (int j = 1;j <= N;j++)
        {
            if(!vis[j] && tmp > dis[j])
            {
                tmp = dis[j];
                pos = j;
            }
        }
        if (tmp == INF) return 0;
        vis[pos] = true;
        sum += dis[pos];
        for(int j = 1;j <= N;j++)
        {
            if (!vis[j] && edge[pos][j] < dis[j])
            {
                dis[j] = edge[pos][j];
            }
        }
    }
    return sum;
}

int main()
{
    while (~scanf("%d",&N))
    {
        for (int i = 1;i <= N;i++)
        {
            for (int j = 1;j <= N;j++)
            {
                scanf("%d",&edge[i][j]);
            }
        }
        int res = prim();
        printf("%d\n",res);
    }
    return 0;
}

Prim算法O(ElogV)

#include<iostream>
#include<vector>
#include<queue>
#include<utility>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
typedef __int64 LL;
typedef pair<int,int>pii;  //first  最短距离  second 顶点编号
const int INF = 0x3f3f3f3f;
const int MAX = 105;
struct edge{
    int to,cost;
    edge(int t,int c):to(t),cost(c){}
};
vector<edge>G[MAX];
int N,dis[MAX];
bool vis[MAX];

int prim()
{
    int res = 0;
    priority_queue<pii,vector<pii>,greater<pii> >que;
    memset(dis,INF,sizeof(dis));
    memset(vis,false,sizeof(vis));
    dis[1] = 0;
    que.push(pii(0,1));
    while (!que.empty())
    {
        pii p = que.top();
        que.pop();
        int v = p.second;
        if (vis[v] || p.first > dis[v]) continue;
        vis[v] = true;
        res += dis[v];
        for (int i = 0;i < G[v].size();i++)
        {
            edge e = G[v][i];
            if (dis[e.to] >  e.cost)
            {
                dis[e.to] = e.cost;
                que.push(pii(dis[e.to],e.to));
            }
        }

    }
    return res;
} 

int main()
{
    while (~scanf("%d",&N))
    {
        int tmp;
        for (int i = 1;i <= N;i++)
        {
            G[i].clear();
            for (int j = 1;j <= N;j++)
            {
                scanf("%d",&tmp);
                G[i].push_back(edge(j,tmp));
            }
        }
        int res = prim();
        printf("%d\n",res);
    }
    return 0;
}

Kruskal算法O(ElogV)

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int INF = 0x3f3f3f3f;
const int MAX = (105*105-105)/2;
struct Edge{
    int u,v,w;
};
int N,father[MAX],rk[MAX];
struct Edge edge[MAX];

bool cmp(Edge x,Edge y)
{
    return x.w < y.w;
}

void init()
{
    memset(father,0,sizeof(father));
    memset(rk,0,sizeof(rk));
    for (int i = 0;i <= N;i++)
    {
        father[i] = i;
    }
}

int find(int x)
{
    int r = x;
    while (father[r] != r)
    {
        r = father[r];
    }
    int i = x,j;
    while (i != r)
    {
        j = father[i];
        father[i] = r;
        i = j;
    }
    return r;
}
/*int find(int x)
{
    return x == father[x]?x:father[x] = find(father[x]);
}*/

void unite(int x,int y)
{
    int fx,fy;
    fx = find(x);
    fy = find(y);
    if (fx == fy)   return;
        if (rk[fx] < rk[fy])
        {
            father[fx] = fy;
        }
        else
        {
            father[fy] = fx;
            if (rk[x] == rk[y])
            {
                rk[x]++;
            }
        }

}

/*void unite(int x,int y)
{
    int fx = find(x),fy = find(y);
    if (fx != fy)
    {
        father[fx] = fy;
    }
}*/

int main()
{
    while (~scanf("%d",&N))
    {
        int tmp,cnt = 0,sum = 0;
        for (int i = 1;i <= N;i++)
        {
            for (int j = 1;j <= N;j++)
            {
                scanf("%d",&tmp);
                if (i < j)
                {
                    edge[cnt].u = i;
                    edge[cnt].v = j;
                    edge[cnt].w = tmp;
                    cnt++;
                }
            }
        }
        init();
        sort(edge,edge+cnt,cmp);
        for (int i = 0;i < cnt;i++)
        {
            int x,y;
            x = find(edge[i].u);
            y = find(edge[i].v);
            if (x != y)
            {
                unite(x,y);
                sum += edge[i].w;
            }
        }
        printf("%d\n",sum);
    }
    return 0;
}

POJ 1258 Agri-Net(最小生成树 Prim+Kruskal)的更多相关文章

  1. 最小生成树 Prim Kruskal

    layout: post title: 最小生成树 Prim Kruskal date: 2017-04-29 tag: 数据结构和算法 --- 目录 TOC {:toc} 最小生成树Minimum ...

  2. 邻接矩阵c源码(构造邻接矩阵,深度优先遍历,广度优先遍历,最小生成树prim,kruskal算法)

    matrix.c #include <stdio.h> #include <stdlib.h> #include <stdbool.h> #include < ...

  3. 数据结构学习笔记05图(最小生成树 Prim Kruskal)

    最小生成树Minimum Spanning Tree 一个有 n 个结点的连通图的生成树是原图的极小连通子图,且包含原图中的所有 n 个结点,并且有保持图连通的最少的边. 树: 无回路   |V|个顶 ...

  4. 布线问题 最小生成树 prim + kruskal

    1 : 第一种 prime     首先确定一个点 作为已经确定的集合 , 然后以这个点为中心 , 向没有被收录的点 , 找最短距离( 到已经确定的点 ) , 找一个已知长度的最小长度的 边 加到 s ...

  5. POJ 1258 Agri-Net(最小生成树,模板题)

    用的是prim算法. 我用vector数组,每次求最小的dis时,不需要遍历所有的点,只需要遍历之前加入到vector数组中的点(即dis[v]!=INF的点).但其实时间也差不多,和遍历所有的点的方 ...

  6. POJ 1258 Agri-Net (最小生成树)

    Agri-Net 题目链接: http://acm.hust.edu.cn/vjudge/contest/124434#problem/H Description Farmer John has be ...

  7. POJ 1751 Highways(最小生成树&Prim)题解

    思路: 一开始用Kruskal超时了,因为这是一个稠密图,边的数量最惨可能N^2,改用Prim. Prim是这样的,先选一个点(这里选1)作为集合A的起始元素,然后其他点为集合B的元素,我们要做的就是 ...

  8. 最小生成树-Prim&Kruskal

    Prim算法 算法步骤 S:当前已经在联通块中的所有点的集合 1. dist[i] = inf 2. for n 次 t<-S外离S最近的点 利用t更新S外点到S的距离 st[t] = true ...

  9. 邻接表c源码(构造邻接矩阵,深度优先遍历,广度优先遍历,最小生成树prim,kruskal算法)

    graph.c #include <stdio.h> #include <stdlib.h> #include <limits.h> #include " ...

随机推荐

  1. swift邮箱手机验证

    import UIKit class Validate: NSObject { //邮箱.手机验证 enum ValidatedType { case Email case PhoneNumber } ...

  2. MyBatis拦截器原理探究

    MyBatis拦截器介绍 MyBatis提供了一种插件(plugin)的功能,虽然叫做插件,但其实这是拦截器功能.那么拦截器拦截MyBatis中的哪些内容呢? 我们进入官网看一看: MyBatis 允 ...

  3. Mybatis解析动态sql原理分析

    前言 废话不多说,直接进入文章. 我们在使用mybatis的时候,会在xml中编写sql语句. 比如这段动态sql代码: <update id="update" parame ...

  4. Theano2.1.21-基础知识之theano中多核的支持

    来自:http://deeplearning.net/software/theano/tutorial/multi_cores.html Multi cores support in Theano 一 ...

  5. 眼保Guide

    1.睡前不要玩手机,特别是关灯玩手机!否则第二天早上你就会感到眼睛模糊了.长久下去就会形成近视或者近视加深. 2.早上起床半小时内不要戴眼镜,不要看手机.电脑等一切电子屏幕,甚至不要看书.这段时间是眼 ...

  6. JAVA_集合框架虐我千百遍,虐也是一种进步

    1.Collection和Collections区别: Collection是java的一个集合接口,集合类的顶级接口 Collections是一个包装类(工具类),不能被实例化(由于其构造函数设为私 ...

  7. 在nodeJs的Express框架下用TypeScript编写router路由出现import关键字错误的解决方案

    问题出现场景 在项目中采用nodejs做中间层,做页面的首屏渲染,同时采用express作为主web框架,其中express的router页面路由我采用ts语言来编写.如下: //page.ts 文件 ...

  8. HTML5+JS 《五子飞》游戏实现(八)人机对战

    要想实现人机对战,就必须让电脑自动下棋,而且要知道自动去查找对方的棋子,看看有没有可以挑一对的,有没有可以夹一个的,这样下起来才有意思. 当电脑用户下完棋后,电脑应立即搜索用户的棋子,然后如果没有被吃 ...

  9. BroadcoastReceiver之短信到来监听和获取内容

    废话就不说了,新建类继承,然后配置Manifest.xml:如下 <!--需要给一个接收短信的权限 --> <uses-permission android:name="a ...

  10. json写入new_hello文件

    #写入new文件 import json dic = {'name':'alex'} i = 8 s = 'hello' l = [11,22] f = open("new_hello&qu ...