HDU 1863 畅通工程 (prim + kruskal)

Description

省政府“畅通工程”的目标是使全省任何两个村庄间都可以实现公路交通(但不一定有直接的公路相连,只要能间接通过公路可达即可)。经过调查评估,得到的统计表中列出了有可能建设公路的若干条道路的成本。现请你编写程序,计算出全省畅通需要的最低成本。 
 

Input

测试输入包含若干测试用例。每个测试用例的第1行给出评估的道路条数 N、村庄数目M ( < 100 );随后的 N 
行对应村庄间道路的成本,每行给出一对正整数,分别是两个村庄的编号,以及此两村庄间道路的成本(也是正整数)。为简单起见,村庄从1到M编号。当N为0时,全部输入结束,相应的结果不要输出。 
 

Output

对每个测试用例,在1行里输出全省畅通需要的最低成本。若统计数据不足以保证畅通,则输出“?”。 
 

Sample Input

     
     
     
     
3 3 1 2 1 1 3 2 2 3 4 1 3 2 3 2 0 100
 

Sample Output

     
     
     
     
3 ?

套路题,然而目前我还是只会prim算法;

有个奇怪的套路, 在prim函数中;

如果点从0开始,i 从 1 , j 从0 ; 如果点从1开始,则i j 都从 1 开始;

AC代码:

#include <bits/stdc++.h>
#define MAX 99999999
#define N 200
using namespace std ;
int m , n ,ma[N][N],dis[N],vis[N];
void prime()
{
	int mini , k ,ans ;
	ans = 0;
	for(int i = 1; i<=n;i++)
	{
		dis[i]=ma[1][i];
	}
	vis[1]=0;
	for(int i = 1 ; i<=n;i++)
	{
		mini = MAX;
		for(int j = 1 ; j<=n;j++)
		{
			if(!vis[j]&&mini>dis[j])
			{
				mini = dis[j];
				k = j;
			}
		}
		if(mini == MAX) 
		{
			printf("?\n");
			return ; 
		}
		vis[k]=1;
		ans+=mini;
		for(int j = 1 ; j<=n;j++)
		{
			if(!vis[j]&&dis[j]>ma[k][j])
			{
				dis[j]=ma[k][j];
			}
		}
	}
	printf("%d\n",ans);
}
int main()
{
	while(cin>>m>>n)
	{
		if(m==0) break;
		for(int i = 1 ;i<=n;i++)
		{
			for(int j = 1 ; j <=n;j++)
			{
				ma[i][j]=MAX;
			}
			vis[i]=0;
			dis[i]=MAX;
			ma[i][i]=0;
		}
		for(int i = 1 ;i<=m;i++)
		{
			int a , b , len ;
			cin>>a>>b>>len;
			if(ma[a][b]>len)
			{
				ma[a][b]=ma[b][a]=len;
			}
		}
		prime();
	}	
	return 0 ;
}


kruskal

AC:

    #include <bits/stdc++.h>
    using namespace std ;
    int pre[20000], n , m;
    struct node {
        int from;
        int to;
        int val;
    }ma[20000];

    int find(int x )
    {
        if(pre[x]!=x)
            return pre[x]=find(pre[x]);
        return x ;
    }

    bool cmp(node a , node b )
    {
        return a.val < b.val;
    }

    void kru()
    {
        int ans , count ;
        ans = count  = 0 ;
        for(int i =  1 ; i<=m;i++)
        {
            int u = find(ma[i].from);
            int v = find(ma[i].to);
            if(u!=v)
            {
                pre[u]=v;
                ans+=ma[i].val;
                count++;
            }
            if(count == n-1  )
                break;
        }
        if(count == n-1)
            printf("%d\n",ans);
        else printf("?\n");
    }

    int main()
    {
        while(cin>>m>>n)
        {
            if(m==0) break;
            for(int i = 1 ; i <=n ; i++)
            {
                pre[i]=i;
            }
            memset(ma,0,sizeof(ma));
            for(int i = 1 ; i <=m ;i++)
            {
                cin>>ma[i].from>>ma[i].to>>ma[i].val;
            }
            sort(ma,ma+m,cmp);
            kru();
        }
    }


你可能感兴趣的:(HDU 1863 畅通工程 (prim + kruskal))