暑假集训日记--8.7--搜索+图论

今天终于开始看图论了。上午A了一道搜索的题,然后就开始看学的相当渣的图论,几乎就是从零开始。

先看了看树的相关知识……发现略微有些难懂。于是看了最小生成树。有几个题是用最小生成树去做的。所以又看到最小生成树。


首先关于树的一个定理:N个点用N-1条边连成一个连通块,形成的图形只可能是树。

因为N个点的图,边一定大于等于N-1,图的最小生成树(MST)就是在这些边中选出N-1条边连接所有的N个点,所得权值最小。

参考资料:信息学奥赛一本通……


最小生成树就是用来解决用最少的代价或者说长度来解决n-1条边连接n个点的问题。


Prim算法:


以一个点为进入最小生成树的点,之后依次计算其他各点到该点的权值,取最小,然后更新其余权值,循环。

蓝白点思想:白点代表已经进入最小生成树的点,蓝点代表未进入最小生成树的点。

每次循环将一个蓝点u变为白点。

通常以1为起点生成最小生成树。

以一个例题为例:

Problem 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
这是一个最小生成树的比较简单的一个题。矩阵表示n个村庄之间的距离,求将全部村庄连接起来的最小距离

源代码:(可能更直观)

#include <iostream>

#include <algorithm>

#include <cstring>

#include <string>

#define MAX 0x7fffffff

using namespace std;

int map[10000][10000];

int visit[10000],dis[100000];

int main()

{

    int n;

    while(cin >> n)

    {

    for (int i = 1; i <= n; i++) //输入村庄的距离

        for (int j = 1; j <= n; j++)

            cin >> map[i][j];

    memset(visit,0,sizeof(visit));

    for (int i = 1; i <= n; i++)//以第一个点为起点生成最小生成树,表示后面每个点和第一个点的权值

        dis[i] = map[1][i];

    dis[1] = 0;

    int sum = 0;

    visit[1] = 1;

    for (int i = 1; i <= n; i++)

    {

        int flag = 1;

        int minn = MAX;

        for (int j = 1; j <= n; j++) //找最小值

            if (visit[j] != 1 && dis[j] < minn)

            {

                minn = dis[j];

                flag = j;

            }

        visit[flag] = 1;

        sum += dis[flag];

        for (int j = 1; j <= n; j++)

            if (dis[j] > map[flag][j])

                dis[j] = map[flag][j];

    }

        cout << sum << endl;

    }

    return 0;

}

今天还有两道题没A一直在超时……再去弄弄

这只是最基础的最小生成树……明天看Kruskal算法。。还有好多要学习的东西。。

继续努力继续努力!

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值