hdu 3371 最小生成树prim算法

Connect the Cities

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 8992    Accepted Submission(s): 2519

Problem Description

In 2100, since the sea level rise, most of the cities disappear. Though some survived cities are still connected with others, but most of them become disconnected. The government wants to build some roads to connect all of these cities again, but they don’t want to take too much money.

Input

The first line contains the number of test cases.
Each test case starts with three integers: n, m and k. n (3 <= n <=500) stands for the number of survived cities, m (0 <= m <= 25000) stands for the number of roads you can choose to connect the cities and k (0 <= k <= 100) stands for the number of still connected cities.
To make it easy, the cities are signed from 1 to n.
Then follow m lines, each contains three integers p, q and c (0 <= c <= 1000), means it takes c to connect p and q.
Then follow k lines, each line starts with an integer t (2 <= t <= n) stands for the number of this connected cities. Then t integers follow stands for the id of these cities.

Output

For each case, output the least money you need to take, if it’s impossible, just output -1.

Sample Input

1

6 4 3

1 4 2

2 6 1

2 3 5

3 4 33

2 1 2

2 1 3

3 4 5 6

Sample Output

1

Author

dandelion

==================================================

也是经典的prim算法,就是处理有些麻烦,自己不是很细心

在定义了一个全局变量n后,又定义了一个局部变量n,导致出错很多次,总是调试不出来

并且,看别人的代码改了自己的代码,当n错误处理以后,又陷入输出-1的陷阱内,一波三折啊

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <algorithm>

#define Maxint 0x7fffffff

int map[505][505],visit[505],low[505];
int n;

int prim()
{
    int i,j,pos=1,minn,sum=0;
    memset(visit,0,sizeof(visit));
    visit[pos]=1;

    for(i=1;i<=n;i++)
    {
        if(i!=pos)
        {
            low[i]=map[pos][i];
        }
    }

    for(i=1;i<n;i++)
    {
        minn=Maxint;pos=-1;//判断图的连通性
        for(j=1;j<=n;j++)
        {
            if(visit[j]==0 && minn>low[j])
            {
                minn=low[j];
                pos=j;
            }
        }

        if(pos == -1)return -1;
        visit[pos]=1;
        sum+=minn;

        for(j=1;j<=n;j++)
        {
            if(visit[j] == 0&&low[j]>map[pos][j])
            {
                low[j]=map[pos][j];
            }
        }
    }
    return sum;
}

int main()
{
    int m,k,t;
    int i,j;
    int p,q,c;
    int y,s;
    int str[505];
    scanf("%d",&t);
    while(t--)
    {
        scanf("%d%d%d",&n,&m,&k);
        for(i=1;i<=n;i++)
            for(j=1;j<=n;j++)
            {
                if(i==j)map[i][j]=0;
                else
                map[i][j]=Maxint;
                str[i]=Maxint;
            }

        for(i=1;i<=m;i++)
        {
            scanf("%d%d%d",&p,&q,&c);
            if(c<map[p][q])
            map[p][q]=map[q][p]=c;
        }
        for(i=1;i<=k;i++)
        {
            scanf("%d",&y);
            for(j=1;j<=y;j++)
            {
                scanf("%d",&str[j]);
            }
            for(j=1;j<=y;j++)
            {
                for(s=j+1;s<=y;s++)
                    map[str[j]][str[s]]=map[str[s]][str[j]]=0;
            }
        }
        bool flag=true;
        int result=prim();
        //for(i=1;i<=n;i++)
         //   if(visit == 0)
       // {
        //    flag=false;
        //}
        //if(flag)
        printf("%d\n",result);
       // else
           // printf("-1\n");
    }
    return 0;
}

/*

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
#define INF 0x3f3f3f3f
#define MAXN 510

int map[MAXN][MAXN], lowcost[MAXN];
bool visit[MAXN];
int alr[MAXN];
int num, sum;

void prim()
{
    int temp, k;
    memset(visit, false, sizeof(visit));
    for(int i = 1; i <= num; ++i)
        lowcost[i] = map[1][i];
    sum = 0;
    visit[1] = true;
    for(int i = 1; i <= num; ++i)
    {
        temp = INF;
        for(int j = 1; j <= num; ++j)
            if(!visit[j] && temp > lowcost[j])
                temp = lowcost[k = j];
        if(temp == INF)
            break;
        visit[k] = 1;
        sum += temp;
        for(int j = 1; j <= num; ++j)
            if(!visit[j] && lowcost[j] > map[k][j])
                lowcost[j] = map[k][j];
    }
}

int main()
{
    int ncase;
    int road, already;
    int a, b, cost;
    int nodenum, node;
    bool flag;
    scanf("%d", &ncase);
    while(ncase--)
    {
        flag = true;
        memset(alr, INF, sizeof(alr));
        memset(map, INF, sizeof(map));
        scanf("%d%d%d", &num, &road, &already);
        for(int i = 1; i <= road; ++i)
        {
            scanf("%d%d%d", &a, &b, &cost);
            if(cost < map[a][b])
                map[a][b] = map[b][a] = cost;
        }
        for(int i = 1; i <= already; ++i) //处理这些权值为0的边
        {
            scanf("%d", &nodenum);
            for(int j = 1; j <= nodenum; ++j)
                scanf("%d", &alr[j]);
            int k;
            for(int j = 1; j < nodenum; ++j)
            {
                k = j + 1;
                map[alr[j]][alr[k]] = map[alr[k]][alr[j]] = 0;
            }
        }
        prim();
        for(int i = 1; i <= num; ++i) //判断图的连通性
            if(visit[i] == false)
                flag = false;
        if(flag)
            printf("%d\n", sum);
        else
            printf("-1\n");
    }
    return 0;
}

*/

  给出了两种判断图连通的方法

hdu 3371 最小生成树prim算法,布布扣,bubuko.com

时间: 2024-10-20 00:10:45

hdu 3371 最小生成树prim算法的相关文章

hdu 3371 最小生成树 prim

http://acm.hdu.edu.cn/showproblem.php?pid=3371 题目大意:告诉你有几座城市,再告诉你哪两座城市之间建路要多少钱,在给你哪几个城市之间已经有路,不需要再建.要求的是要使所有城市之间连通最小要花费多少钱. 这里我用了prim算法..保存城市之间的权值,对于已经建好的城市,将他们的权值赋为0.还有就是要判断是否能找出最小生成树,如果不可以就输出-1,如果在遍历点的时候,并不能找出一个最小的边,那么肯定就是没有最小生成树.(注意要在每个kase开始的时候将所

hdu 3371(prim算法)

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3371 Connect the Cities Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 10313    Accepted Submission(s): 2937 Problem Description In 2100, since th

hdu 1233(最小生成树 prim算法)

还是畅通工程 Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)Total Submission(s): 43080    Accepted Submission(s): 19636 Problem Description 某省调查乡村交通状况,得到的统计表中列出了任意两村庄间的距离.省政府"畅通工程"的目标是使全省任何两个村庄间都可以实现公路交通(但不一定有直接的公路相

hdu 1301 最小生成树prim实现

http://acm.hdu.edu.cn/showproblem.php?pid=1301 Jungle Roads Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)Total Submission(s): 4145    Accepted Submission(s): 3020 Problem Description The Head Elder of the tropica

最小生成树--prim算法

一个无向图G的最小生成树就是由该图的那些连接G的所有顶点的边构成的树,且其总价值最低,因此,最小生成树存在的充分必要条件为图G是连通的,简单点说如下: 1.树的定义:有n个顶点和n-1条边,没有回路的称为树 生成树的定义:生成树就是包含全部顶点,n-1(n为顶点数)条边都在图里就是生成树 最小:指的是这些边加起来的权重之和最小 2.判定条件:向生成树中任加一条边都一定构成回路 充分必要条件:最小生成树存在那么图一定是连通的,反过来,图是连通的则最小生成树一定存在 上图的红色的边加上顶点就是原图的

POJ1258最小生成树(prim算法)

POJ1258 思路:首先把第一个结点加入树中,每次往树中加入一个结点,加入的结点必须是与当前树中的结点距离最小那个点,这样每次把结点加入树中选取的都是最小权值,循环n-1次后把所有结点都加入树中. #include<iostream> #include<cstdio> #include<cstring> using namespace std; const int MAXN = 1e9; //创建map二维数组储存图表,low数组记录每2个点间最小权值,vis数组标记

poj1789Truck History(最小生成树prim算法)

题目链接: 啊哈哈,点我点我 思路:根据字符串中不同的长度建图,然后求图的最小生成树.. 题目: Truck History Time Limit: 2000MS   Memory Limit: 65536K Total Submissions: 18272   Accepted: 7070 Description Advanced Cargo Movement, Ltd. uses trucks of different types. Some trucks are used for vege

数据结构:最小生成树--Prim算法

最小生成树:Prim算法 最小生成树 给定一无向带权图,顶点数是n,要使图连通只需n-1条边,若这n-1条边的权值和最小,则称有这n个顶点和n-1条边构成了图的最小生成树(minimum-cost spanning tree). Prim算法 Prim算法是解决最小生成树的常用算法.它采取贪心策略,从指定的顶点开始寻找最小权值的邻接点.图G=<V,E>,初始时S={V0},把与V0相邻接,且边的权值最小的顶点加入到S.不断地把S中的顶点与V-S中顶点的最小权值边加入,直到所有顶点都已加入到S中

最小生成树のprim算法

Problem A Time Limit : 1000/1000ms (Java/Other)   Memory Limit : 32768/32768K (Java/Other) Total Submission(s) : 31   Accepted Submission(s) : 10 Problem Description 省政府“畅通工程”的目标是使全省任何两个村庄间都可以实现公路交通(但不一定有直接的公路相连,只要能间接通过公路可达即可).经过调查评估,得到的统计表中列出了有可能建设公