【 题集 】 【kuangbin带你飞】专题六 最小生成树

来源:互联网 发布:kmeans算法 编辑:程序博客网 时间:2024/05/29 11:35

    感觉 差不多了,那题bfs + 最小生成树的,待我以后再补上,感觉最小生成树,应该有一定的理解了吧、、、、

    还有 到底是prim 还是 prime 啊 - -#

A - Jungle Roads


Description


The Head Elder of the tropical island of Lagrishan has a problem. A burst of foreign aid money was spent on extra roads between villages some years ago. But the jungle overtakes roads relentlessly, so the large road network is too expensive to maintain. The Council of Elders must choose to stop maintaining some roads. The map above on the left shows all the roads in use now and the cost in aacms per month to maintain them. Of course there needs to be some way to get between all the villages on maintained roads, even if the route is not as short as before. The Chief Elder would like to tell the Council of Elders what would be the smallest amount they could spend in aacms per month to maintain roads that would connect all the villages. The villages are labeled A through I in the maps above. The map on the right shows the roads that could be maintained most cheaply, for 216 aacms per month. Your task is to write a program that will solve such problems.

Input

The input consists of one to 100 data sets, followed by a final line containing only 0. Each data set starts with a line containing only a number n, which is the number of villages, 1 < n < 27, and the villages are labeled with the first n letters of the alphabet, capitalized. Each data set is completed with n-1 lines that start with village labels in alphabetical order. There is no line for the last village. Each line for a village starts with the village label followed by a number, k, of roads from this village to villages with labels later in the alphabet. If k is greater than 0, the line continues with data for each of the k roads. The data for each road is the village label for the other end of the road followed by the monthly maintenance cost in aacms for the road. Maintenance costs will be positive integers less than 100. All data fields in the row are separated by single blanks. The road network will always allow travel between all the villages. The network will never have more than 75 roads. No village will have more than 15 roads going to other villages (before or after in the alphabet). In the sample input below, the first data set goes with the map above.

Output

The output is one integer per line for each data set: the minimum cost in aacms per month to maintain a road system that connect all the villages. Caution: A brute force solution that examines every possible set of roads will not finish within the one minute time limit.

Sample Input

9A 2 B 12 I 25B 3 C 10 H 40 I 8C 2 D 18 G 55D 1 E 44E 2 F 60 G 38F 0G 1 H 35H 1 I 353A 2 B 10 C 40B 1 C 200

Sample Output

21630

    一开始以为输入麻烦不想做,其实还是挺简单的、、、

   

#include <stdio.h>#include <iostream>#include <algorithm>#include <map>#include <string.h>using namespace std;#define N 110#define Max 0x3fffffffint tt[N][N];int vis[N];int dis[N];int n, m;int prim(){    int i, j, k;    int ans = 0;    int min, t;    memset(vis, 0, sizeof(vis));    for(i = 1; i <= n; i ++)    {        dis[i] = tt[1][i];    }    vis[1] = 1;    for(i = 1; i < n; i ++)    {        min = Max;        for(j = 1; j <= n; j ++)        {            if(!vis[j] && dis[j] < min)            {                min = dis[j];                t = j;            }        }        if(min == Max)              break;        ans += min;        vis[t] = 1;        for(k = 1; k <= n; k ++)        {            if(!vis[k] && dis[k] > tt[t][k])            dis[k] = tt[t][k];        }    }    return ans;}void init(){    for(int i = 0; i <= n; i ++)    {        for(int j = 0; j <= n; j ++)        {            if(i == j)                tt[i][j] = 0;            else                tt[i][j] = Max;        }    }}int main(){    char t[10];    char t1[10];    int a, b;    while(~scanf("%d",&n), n)    {        init();        for(int i = 0; i < n - 1; i ++)        {            scanf("%s%d",t, &a);            int tmp_1 = t[0] - 'A' + 1;            //printf("%s%d",t,a);            for(int j = 0; j < a; j ++)            {                scanf("%s%d",t1, &b);                int tmp_2 = t1[0] -'A' + 1;                tt[tmp_1][tmp_2] = b;                tt[tmp_2][tmp_1] = b;                //printf("%c %c %d \n",t[0],t1[0] ,tt[tmp_1][tmp_2]);            }            //printf("\n");        }        printf("%d\n",prim());    }}

B - Networking


Description

You are assigned to design network connections between certain points in a wide area. You are given a set of points in the area, and a set of possible routes for the cables that may connect pairs of points. For each possible route between two points, you are given the length of the cable that is needed to connect the points over that route. Note that there may exist many possible routes between two given points. It is assumed that the given possible routes connect (directly or indirectly) each two points in the area.
Your task is to design the network for the area, so that there is a connection (direct or indirect) between every two points (i.e., all the points are interconnected, but not necessarily by a direct cable), and that the total length of the used cable is minimal.

Input

The input file consists of a number of data sets. Each data set defines one required network. The first line of the set contains two integers: the first defines the number P of the given points, and the second the number R of given routes between the points. The following R lines define the given routes between the points, each giving three integer numbers: the first two numbers identify the points, and the third gives the length of the route. The numbers are separated with white spaces. A data set giving only one number P=0 denotes the end of the input. The data sets are separated with an empty line.
The maximal number of points is 50. The maximal length of a given route is 100. The number of possible routes is unlimited. The nodes are identified with integers between 1 and P (inclusive). The routes between two points i and j may be given as i j or as j i.

Output

For each data set, print one number on a separate line that gives the total length of the cable used for the entire designed network.

Sample Input

1 02 31 2 372 1 171 2 683 71 2 192 3 113 1 71 3 52 3 893 1 911 2 325 71 2 52 3 72 4 84 5 113 5 101 5 64 2 120

Sample Output

0171626

   

#include<stdio.h>#include<string.h>#define Max 1000000int ans;int map[110][110];int dis[110];int vis[110];int n;int prim(){    int i, j, k;    int ans = 0;    int min, t;    memset(vis, 0, sizeof(vis));    for(i = 1; i <= n; i ++)    {        dis[i] = map[1][i];    }    vis[1] = 1;    for(i = 1; i < n; i ++)    {        min = Max;        for(j = 1; j <= n; j ++)        {            if(!vis[j] && dis[j] < min)            {                min = dis[j];                t = j;            }        }        if(min == Max)              break;        ans += min;        vis[t] = 1;        for(k = 1; k <= n; k ++)        {            if(!vis[k] && dis[k] > map [t][k])            dis[k] = map[t][k];        }    }    return ans;}void init(int n){    for(int i = 0; i <= n; i ++)    {        for(int j = 0; j <= n; j ++)        {            if(i == j)            {                map[i][j] = 0;                continue;            }            map[i][j] = Max;        }    }}int main(){    int i;    int a, b, c;    int m;    while(~scanf("%d",&n)&&n)    {        scanf("%d",&m);        init(n);        for(i = 0; i < m; i ++)        {            scanf("%d%d%d", &a, &b, &c);            if(map[a][b] > c)            {                map[a][b] = c;                map[b][a] = c;            }        }        printf("%d\n",prim());    }    return 0;}

D - Constructing Roads


Description

There are N villages, which are numbered from 1 to N, and you should build some roads such that every two villages can connect to each other. We say two village A and B are connected, if and only if there is a road between A and B, or there exists a village C such that there is a road between A and C, and C and B are connected.

We know that there are already some roads between some villages and your job is the build some roads such that all the villages are connect and the length of all the roads built is minimum.

Input

The first line is an integer N (3 <= N <= 100), which is the number of villages. Then come N lines, the i-th of which contains N integers, and the j-th of these N integers is the distance (the distance should be an integer within [1, 1000]) between village i and village j.

Then there is an integer Q (0 <= Q <= N * (N + 1) / 2). Then come Q lines, each line contains two integers a and b (1 <= a < b <= N), which means the road between village a and village b has been built.

Output

You should output a line contains an integer, which is the length of all the roads to be built such that all the villages are connected, and this value is minimum.

Sample Input

30 990 692990 0 179692 179 011 2

Sample Output

179

    先输入一组表示 点与点之间的距离,后面一组是表示该两点之间存在桥,所以只需要置零即可。

#include <stdio.h>#include <iostream>#include <algorithm>#include <string.h>using namespace std;#define N 120#define Max 1 << 29int vis[N];int dis[N];int map[N][N];int n, m;int prime(){    int i, j, k;    int ans = 0;    int min, t;    memset(vis, 0, sizeof(vis));    for(i = 1; i <= n; i ++)    {        dis[i] = map[1][i];    }    vis[1] = 1;    for(i = 1; i < n; i ++)    {        min = Max;        for(j = 1; j <= n; j ++)        {            if(!vis[j] && dis[j] < min)            {                min = dis[j];                t = j;            }        }        if(min == Max)              break;        ans += min;        vis[t] = 1;        for(k = 1; k <= n; k ++)        {            if(!vis[k] && dis[k] > map [t][k])            dis[k] = map[t][k];        }    }    return ans;}void init(){    for(int i = 0; i <= n; i ++)    {        for(int j = 0; j <= n; j ++)        {            if(i == j)                map[i][j] = 0;            else                map[i][j] = Max;        }    }}int main(){    int a, b;    while(~scanf("%d",&n))    {        init();        for(int i = 1; i <= n; i ++)        {            for(int j = 1; j <= n; j ++)            {                scanf("%d",&map[i][j]);            }        }        scanf("%d",&m);        for(int i = 0; i < m; i ++)        {            scanf("%d%d",&a,&b);            map[a][b] = map[b][a] = 0;        }        printf("%d\n",prime());    }}

   

H - Highways


Description

The island nation of Flatopia is perfectly flat. Unfortunately, Flatopia has a very poor system of public highways. The Flatopian government is aware of this problem and has already constructed a number of highways connecting some of the most important towns. However, there are still some towns that you can't reach via a highway. It is necessary to build more highways so that it will be possible to drive between any pair of towns without leaving the highway system.

Flatopian towns are numbered from 1 to N and town i has a position given by the Cartesian coordinates (xi, yi). Each highway connects exaclty two towns. All highways (both the original ones and the ones that are to be built) follow straight lines, and thus their length is equal to Cartesian distance between towns. All highways can be used in both directions. Highways can freely cross each other, but a driver can only switch between highways at a town that is located at the end of both highways.

The Flatopian government wants to minimize the cost of building new highways. However, they want to guarantee that every town is highway-reachable from every other town. Since Flatopia is so flat, the cost of a highway is always proportional to its length. Thus, the least expensive highway system will be the one that minimizes the total highways length.

Input

The input consists of two parts. The first part describes all towns in the country, and the second part describes all of the highways that have already been built.

The first line of the input file contains a single integer N (1 <= N <= 750), representing the number of towns. The next N lines each contain two integers, xi and yi separated by a space. These values give the coordinates of ith town (for i from 1 to N). Coordinates will have an absolute value no greater than 10000. Every town has a unique location.

The next line contains a single integer M (0 <= M <= 1000), representing the number of existing highways. The next M lines each contain a pair of integers separated by a space. These two integers give a pair of town numbers which are already connected by a highway. Each pair of towns is connected by at most one highway.

Output

Write to the output a single line for each new highway that should be built in order to connect all towns with minimal possible total length of new highways. Each highway should be presented by printing town numbers that this highway connects, separated by a space.

If no new highways need to be built (all towns are already connected), then the output file should be created but it should be empty.

Sample Input

91 50 0 3 24 55 10 45 21 25 331 39 71 2

Sample Output

1 63 74 95 78 3


    这题是要求,还需要建立哪些桥,一开始用kruskal,半天搞不出来,后来转prim 了, 恶心了我好久,下次有空再看吧。。。

   

#include <stdio.h>#include <algorithm>#include <string.h>#include <math.h>using namespace std;#define N 800#define Max 0x3fffffffint n, m;int x[N];int y[N];int dis[N];int vis[N];int map[N][N];int path[N];void prim(){    int ans = 0;    int min, t;    memset(vis, 0, sizeof(vis));    for(int i = 1; i <= n; i ++)    {        dis[i] = map[1][i];        path[i] = 1;    }    vis[1] = 1;    for(int i = 1; i < n; i ++)    {        min = Max;        for(int j = 1; j <= n; j ++)        {            if(!vis[j] && dis[j] < min)            {                min = dis[j];                t = j;            }        }        //if(min == Max)          //    break;        ans += min;        vis[t] = 1;        if(map[path[t]][t] != 0)            printf("%d %d\n", t, path[t]);        for(int k = 1; k <= n; k ++)        {            if(!vis[k] && dis[k] > map [t][k])            {                dis[k] = map[t][k];                path[k] = t;            }        }    }}void init(){    for(int i = 1; i <= n; i ++)    {        for(int j = 1; j <= n; j ++)        {            if(i == j)            {                map[i][j] = 0;            }            else                map[i][j] = Max;        }    }}int main(){    int a, b;    while(~scanf("%d",&n))    {        init();        for(int i = 1; i <= n; i ++)        {            scanf("%d%d",&x[i],&y[i]);        }        for(int i = 1; i <= n; i ++)        {            for(int j = 1; j <= n; j ++)            {                map[i][j] = (x[i] - x[j])*(x[i] - x[j]) + (y[i] - y[j])*(y[i]- y[j]);                map[j][i] = map[i][j];            }        }        scanf("%d",&m);        for(int i = 1; i <= m; i ++)        {            scanf("%d%d",&a, &b);            map[a][b] = map[b][a] = 0;        }        prim();    }}

I - Agri-Net

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

40 4 9 214 0 8 179 8 0 1621 17 16 0

Sample Output

28


纯 模版

#include <stdio.h>#include <iostream>#include <algorithm>#include <string.h>using namespace std;#define N 120#define Max 1 << 29int vis[N];int dis[N];int map[N][N];int n;int prime(){    int i, j, k;    int ans = 0;    int min, t;    memset(vis, 0, sizeof(vis));    for(i = 1; i <= n; i ++)    {        dis[i] = map[1][i];    }    vis[1] = 1;    for(i = 1; i < n; i ++)    {        min = Max;        for(j = 1; j <= n; j ++)        {            if(!vis[j] && dis[j] < min)            {                min = dis[j];                t = j;            }        }        if(min == Max)              break;        ans += min;        vis[t] = 1;        for(k = 1; k <= n; k ++)        {            if(!vis[k] && dis[k] > map [t][k])            dis[k] = map[t][k];        }    }    return ans;}int main(){    while(~scanf("%d",&n))    {        for(int i = 1; i <= n; i ++)        {            for(int j = 1; j <= n; j ++)            {                scanf("%d",&map[i][j]);            }        }        printf("%d\n",prime());    }}


L - 还是畅通工程


Description

某省调查乡村交通状况,得到的统计表中列出了任意两村庄间的距离。省政府“畅通工程”的目标是使全省任何两个村庄间都可以实现公路交通(但不一定有直接的公路相连,只要能间接通过公路可达即可),并要求铺设的公路总长度为最小。请计算最小的公路总长度。
 

Input

测试输入包含若干测试用例。每个测试用例的第1行给出村庄数目N ( < 100 );随后的N(N-1)/2行对应村庄间的距离,每行给出一对正整数,分别是两个村庄的编号,以及此两村庄间的距离。为简单起见,村庄从1到N编号。
当N为0时,输入结束,该用例不被处理。
 

Output

对每个测试用例,在1行里输出最小的公路总长度。
 

Sample Input

31 2 11 3 22 3 441 2 11 3 41 4 12 3 32 4 23 4 50
 

Sample Output

35

Hint

    简单的中文模版题!!

 

#include <stdio.h>#include <iostream>#include <algorithm>#include <string.h>using namespace std;#define N 120#define Max 1 << 29int vis[N];int dis[N];int map[N][N];int n;int prime(){    int i, j, k;    int ans = 0;    int min, t;    memset(vis, 0, sizeof(vis));    for(i = 1; i <= n; i ++)    {        dis[i] = map[1][i];    }    vis[1] = 1;    for(i = 1; i < n; i ++)    {        min = Max;        for(j = 1; j <= n; j ++)        {            if(!vis[j] && dis[j] < min)            {                min = dis[j];                t = j;            }        }        if(min == Max)              break;        ans += min;        vis[t] = 1;        for(k = 1; k <= n; k ++)        {            if(!vis[k] && dis[k] > map [t][k])            dis[k] = map[t][k];        }    }    return ans;}int main(){    int a, b, c;    while(~scanf("%d",&n))    {        if(n == 0)            break;        for(int i = 0; i < n*(n - 1)/ 2; i ++)        {            scanf("%d%d%d",&a,&b,&c);            map[a][b] = map[b][a] = c;        }        printf("%d\n", prime());    }}


N - 畅通工程再续


Description

相信大家都听说一个“百岛湖”的地方吧,百岛湖的居民生活在不同的小岛中,当他们想去其他的小岛时都要通过划小船来实现。现在政府决定大力发展百岛湖,发展首先要解决的问题当然是交通问题,政府决定实现百岛湖的全畅通!经过考察小组RPRush对百岛湖的情况充分了解后,决定在符合条件的小岛间建上桥,所谓符合条件,就是2个小岛之间的距离不能小于10米,也不能大于1000米。当然,为了节省资金,只要求实现任意2个小岛之间有路通即可。其中桥的价格为 100元/米。
 

Input

输入包括多组数据。输入首先包括一个整数T(T <= 200),代表有T组数据。
每组数据首先是一个整数C(C <= 100),代表小岛的个数,接下来是C组坐标,代表每个小岛的坐标,这些坐标都是 0 <= x, y <= 1000的整数。
 

Output

每组输入数据输出一行,代表建桥的最小花费,结果保留一位小数。如果无法实现工程以达到全部畅通,输出”oh!”.
 

Sample Input

2210 1020 2031 12 21000 1000
 

Sample Output

1414.2oh!


   被这题坑了超级久!!就是要注意10和1000 的判断的时候 是大于等于和小于等于! 还有我一开始连初始化都搞错了,结果还用VC 单步调试  T_T  、、、

   

#include <stdio.h>#include <iostream>#include <algorithm>#include <string.h>#include <math.h>using namespace std;#define N 220#define Max 0x3fffffffstruct node{    int x, y;}po[N];int vis[N];double dis[N];double map[N][N];int n, ok;double prime(){    int i, j, k, t;    double ans = 0;    double min;    memset(vis, 0, sizeof(vis));    memset(dis, 0, sizeof(dis));    for(i = 1; i <= n; i ++)    {        dis[i] = map[1][i];    }    vis[1] = 1;    for(i = 1; i < n; i ++)    {        min = Max;        for(j = 1; j <= n; j ++)        {            if(!vis[j] &&  min - dis[j] > 0.00001)            {                min = dis[j];                t = j;            }        }        if(min == Max)        {            ok = 1;            return 0;        }        ans += min;        vis[t] = 1;        for(k = 1; k <= n; k ++)        {            if(!vis[k] && dis[k] - map [t][k] > 0.00001)            dis[k] = map[t][k];        }    }    return ans;}int main(){    int t;    while(~scanf("%d",&t))    {        while(t --)        {            scanf("%d", &n);            for(int i = 1; i <= n; i ++)            {                scanf("%d%d",&po[i].x, &po[i].y);            }            for(int i = 1; i <= n; i ++)            {                for(int j = 1; j <= n; j ++)                {                    if(i == j)                    {                        map[i][j] = 0;                        continue;                    }                    double tmp1 = (po[i].x - po[j].x) * (po[i].x - po[j].x);                    double tmp2 = (po[i].y - po[j].y) * (po[i].y - po[j].y);                    double tmp3 = sqrt(tmp1 + tmp2);                    //if(tmp3 - 10 > 0.00001 && 1000 - tmp3 > 0.00001)                    if(tmp3 <= 1000 && tmp3 >= 10)                    {                        map[i][j] = map[j][i] = tmp3;                    }                    else                        map[i][j] = map[j][i] = Max;                }            }            ok = 0;            double ttt = prime();            if(ok == 0)            {                printf("%.1f\n", ttt * 100);            }            else                printf("oh!\n");        }    }}


0 0
原创粉丝点击