PIPIOJ 1004: 惠民工程

题目链接:
传送门

题目描述:
市政府“惠民工程”的目标是在全市n个居民点间之架设煤气管道(但不一定有直接的管道相连,只要能间接通过管道可达即可)。很显然最多可架设 n(n-1)/2条管道,然而实际上要连通n个居民点只需架设n-1条管道就可以了。现请你编写程序,计算出该惠民工程需要的最低成本。

输入:
测试输入包含若干测试用例。每个测试用例的第1行给出居民点数目M ( < =100 )、 评估的管道条数 N;随后的 N 行对应居民点间管道的成本,每行给出一对正整数,分别是两个居民点的编号,以及此两居民点间管道的成本(也是正整数)。为简单起见,居民点从1到M编号。

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

样例输入:
3 3
1 2 1
1 3 2
2 3 4
3 1
2 3 2

样例输出:
3
?

prim算法c参考代码:

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

#define INF 0x3f3f3f3f
#define MAX 101

int m,n;
int cost[MAX][MAX];
int dist[MAX];
int visited[MAX];

void prim()
{
    
    
    memset(visited,0,sizeof(visited));
	int i,j,sum=0;
	for(i=1;i<=m;i++)
	 dist[i]=cost[1][i];
	
	visited[1]=1;
	
	for(i=1;i<m;i++)
	{
    
    
		int min=INF,pos=-1;
		for(j=1;j<=m;j++)
		{
    
    
			if(visited[j]==0&&dist[j]<min)
			{
    
    
				min=dist[j];
				pos=j;
			}
		}
		
		if(pos!=-1)
		{
    
    
		 visited[pos]=1;
		 sum+=min;
		}
		else
		 break;
		
		for(j=1;j<=m;j++)
		{
    
    
			if(visited[j]==0&&dist[j]>cost[pos][j])
			 dist[j]=cost[pos][j];
		}
	}
	
	for(i=1;i<=m;i++)
	{
    
    
		if(visited[i]==0)
		 break;
	}
	
	if(i==m+1)
	 printf("%d\n",sum);
	else
	 printf("?\n");
}

int main()
{
    
    
	int i,x,y,z;
	
	while(scanf("%d%d",&m,&n)!=EOF)
	{
    
    
		memset(cost,INF,sizeof(cost));
		for(i=1;i<=m;i++)
		 cost[i][i]=0;
		
		for(i=0;i<n;i++)
		{
    
    
			scanf("%d%d%d",&x,&y,&z);
			cost[x][y]=cost[y][x]=z;
		}
		
		prim();
	}
	return 0;
}

kruskal算法c参考代码:

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

#define MAX 101

int n,m;
int parent[MAX];

typedef struct{
    
    
	int u,v;
	int w;
}Tube,*tube;

Tube a[4951];

int cmp(const void *a,const void *b)
{
    
    
	tube pa=(tube)a;
	tube pb=(tube)b;
	int num1=pa->w;
	int num2=pb->w;
	return num1-num2;
}

void init()
{
    
    
	int i;
	for(i=1;i<=m;i++)
	 parent[i]=i;
}

int find(int x)
{
    
    
	if(x==parent[x])
	 return x;
	else
	 return parent[x]=find(parent[x]);
}

void kruskal()
{
    
    
	qsort(a,n,sizeof(Tube),cmp);
	
	int i,sum=0,count=0;
	for(i=0;i<n;i++)
	{
    
    
		int A=find(a[i].u);
		int B=find(a[i].v);
		if(A!=B)
		{
    
    
			parent[A]=B;
			sum+=a[i].w;
		}
	}
	
	for(i=1;i<=m;i++)
	{
    
    
		if(parent[i]==i)
		 count++;
	}
	
	if(count==1)
	 printf("%d\n",sum);
	else
	 printf("?\n");
}

int main()
{
    
    
	int i;
	
	while(scanf("%d%d",&m,&n)!=EOF)
	{
    
    
	    init();
	    
		for(i=0;i<n;i++)
		  scanf("%d%d%d",&a[i].u,&a[i].v,&a[i].w);
        
        kruskal();
	}
	return 0;
} 

猜你喜欢

转载自blog.csdn.net/qq_46139801/article/details/115278437