[kuangbin带你飞]专题六 最小生成树

A - Jungle Roads 题目链接

#include <stdio.h>
#include <string.h>
#include <math.h>
#include <iostream>
using namespace std;

const int INF=0x3f3f3f3f;
const int MAXN=30;
bool vis[MAXN];
int lowc[MAXN];
int cost[MAXN][MAXN];


int Prim(int n)
{
	int ans=0;
	memset(vis,false,sizeof(vis));
	memset(lowc,0,sizeof(lowc));
	vis[0]=true;
	for(int i=1;i<n;i++)
		lowc[i]=cost[0][i];
	for(int i=1;i<n;i++)
	{
		int minc=INF;
		int p=-1;
		for(int j=0;j<n;j++)
		{
			if(!vis[j]&&minc>lowc[j])
			{
				minc=lowc[j];
				p=j;
			}
		}
		if(minc==INF)
			return -1;
		ans+=minc;
		vis[p]=true;
		for(int j=0;j<n;j++)
		{
			if(!vis[j]&&lowc[j]>cost[p][j])
				lowc[j]=cost[p][j];
		}
	}
	return ans;
}

void init(int n)
{
	for(int i=0;i<n;i++)
		for(int j=0;j<n;j++)
		{
			if(i==j)
				cost[i][j]=0;
			else
				cost[i][j]=cost[j][i]=INF;
		}
}

int main()
{
	int n,m,a;
	char s[10],ss[10];
	while(scanf("%d",&n)==1)
	{
		if(n==0)
			break;
		init(n);
		for(int i=1;i<n;i++)
		{
			scanf("%s%d ",&s,&m);
			for(int j=0;j<m;j++)
			{
				scanf("%s%d ",&ss,&a);
				cost[s[0]-'A'][ss[0]-'A']=cost[ss[0]-'A'][s[0]-'A']=a;
			}
		}	
		printf("%d\n",Prim(n));
	}
    return 0;
}

B -  Networking 题目链接

#include <stdio.h>
#include <string.h>
#include <set>
#include <map>
#include <algorithm>
using namespace std;

const int INF=0x3f3f3f3f;
const int MAXN=59;
bool vis[MAXN];
int lowc[MAXN];
int cost[109][109];

int Prim(int n)
{
	int ans=0;
	memset(vis,false,sizeof(vis));
	vis[1]=true;
	for(int i=2;i<=n;i++)
		lowc[i]=cost[1][i];
	for(int i=2;i<=n;i++)
	{
		int minc=INF;
		int p=-1;
		for(int j=1;j<=n;j++)
		{
			if(!vis[j]&&minc>lowc[j])
			{
				minc=lowc[j];
				p=j;
			}
		}
		if(minc==INF)
			return -1;
		ans+=minc;
		vis[p]=true;
		for(int j=1;j<=n;j++)
		{
			if(!vis[j]&&lowc[j]>cost[p][j])
				lowc[j]=cost[p][j];
		}

	}
	return ans;
}

void init(int n)
{
	for(int i=1;i<=n;i++)
		for(int j=1;j<=n;j++)
			cost[i][j]=cost[j][i]=INF;
}
int main()
{
	int n,m;
	while(scanf("%d",&n)==1)
	{
		if(n==0)
			break;
		scanf("%d",&m);
		init(n);
		while(m--)
		{
			int a,b,time;
			scanf("%d%d%d",&a,&b,&time);
			if(cost[a][b]>time)
			{
				cost[a][b]=cost[b][a]=time;
			}
		}
		/*for(int i=1;i<n;i++)
			for(int j=1;j<=n;j++)
				printf("%d ",cost[i][j]);*/
		printf("%d\n",Prim(n));
	}
    return 0;
}

C -  Building a Space Station 题目链接

#include <stdio.h>
#include <string.h>
#include <math.h>
#include <iostream>
#include <stdlib.h>
using namespace std;

const double INF=0x3f3f3f3f;
const int MAXN=109;
bool vis[MAXN];
double lowc[MAXN];
double cost[MAXN][MAXN];

double Prim(int n)
{
	double ans=0;
	memset(vis,false,sizeof(vis));
	memset(lowc,0,sizeof(lowc));
	vis[0]=true;
	for(int i=1;i<n;i++)
		lowc[i]=cost[0][i];
	for(int i=1;i<n;i++)
	{
		double minc=INF;
		int p=-1;
		for(int j=0;j<n;j++)
		{
			if(!vis[j]&&minc>lowc[j])
			{
				minc=lowc[j];
				p=j;
			}
		}
		if(minc==INF)
			return -1;
		ans+=minc;
		vis[p]=true;
		for(int j=0;j<n;j++)
		{
			if(!vis[j]&&lowc[j]>cost[p][j])
				lowc[j]=cost[p][j];
		}
	}
	return ans;
}

void init(int n)
{
	for(int i=0;i<n;i++)
		for(int j=0;j<n;j++)
		{
			if(i==j)
				cost[i][j]=0;
			else
				cost[i][j]=cost[j][i]=INF;
		}
}

int main()
{
	int n;
	while(scanf("%d",&n)==1)
	{
		if(n==0)
			break;
		init(n);
		for(int i=0;i<n;i++)
		{
			double a[109],b[109],c[109],r[109];
			scanf("%lf%lf%lf%lf",&a[i],&b[i],&c[i],&r[i]);
			for(int j=0;j<i;j++)
			{
				double dist=sqrt((a[i]-a[j])*(a[i]-a[j])+(b[i]-b[j])*(b[i]-b[j])+(c[i]-c[j])*(c[i]-c[j]));
				if(dist<=r[i]+r[j])
					cost[i][j]=cost[j][i]=0;
				else
					cost[i][j]=cost[j][i]=dist-(r[i]+r[j]);
			}
		}
		printf("%.3lf\n",Prim(n));
	}
	return 0;
}

D -  Constructing Roads 题目链接

#include <stdio.h>
#include <string.h>
#include <math.h>
#include <iostream>
#include <stdlib.h>
using namespace std;

const int INF=0x3f3f3f3f;
const int MAXN=109;
bool vis[MAXN];
int lowc[MAXN];
int cost[MAXN][MAXN];


int Prim(int n)
{
	int ans=0;
	memset(vis,false,sizeof(vis));
	memset(lowc,0,sizeof(lowc));
	vis[0]=true;
	for(int i=1;i<n;i++)
		lowc[i]=cost[0][i];
	for(int i=1;i<n;i++)
	{
		int minc=INF;
		int p=-1;
		for(int j=0;j<n;j++)
		{
			if(!vis[j]&&minc>lowc[j])
			{
				minc=lowc[j];
				p=j;
			}
		}
		if(minc==INF)
			return -1;
		ans+=minc;
		vis[p]=true;
		for(int j=0;j<n;j++)
		{
			if(!vis[j]&&lowc[j]>cost[p][j])
				lowc[j]=cost[p][j];
		}
	}
	return ans;
}

void init(int n)
{
	for(int i=0;i<n;i++)
		for(int j=0;j<n;j++)
		{
			if(i==j)
				cost[i][j]=0;
			else
				cost[i][j]=cost[j][i]=INF;
		}
}

int main()
{
	int n;
	scanf("%d",&n);
	for(int i=0;i<n;i++)
		for(int j=0;j<n;j++)
		{
			int a;
			scanf("%d",&a);
			cost[i][j]=a;
		}
	int m;
	scanf("%d",&m);
	while(m--)
	{
		int a,b;
		scanf("%d%d",&a,&b);
		cost[a-1][b-1]=cost[b-1][a-1]=0;
	}
	printf("%d\n",Prim(n));
	return 0;
}

E -  QS Network 题目链接

#include <stdio.h>
#include <string.h>
#include <math.h>
#include <iostream>
#include <stdlib.h>
using namespace std;

const int INF=0x3f3f3f3f;
const int MAXN=1009;
bool vis[MAXN];
int lowc[MAXN];
int pre[MAXN];
int Max[MAXN][MAXN];
bool used[MAXN][MAXN];

int prim(int cost[][MAXN],int n)
{
	int ans=0;
	memset(vis,false,sizeof(vis));
	memset(Max,0,sizeof(Max));
	memset(used,false,sizeof(used));
	vis[0]=true;
	pre[0]=-1;
	for(int i=1;i<n;i++)
	{
		lowc[i]=cost[0][i];
		pre[i]=0;
	}
	lowc[0]=0;
	for(int i=1;i<n;i++)
	{
		int minc=INF;
		int p=-1;
		for(int j=0;j<n;j++)
		{
			if(!vis[j]&&minc>lowc[j])
			{
				minc=lowc[j];
				p=j;
			}
		}
		if(minc==INF)
			return -1;
		ans+=minc;
		vis[p]=true;
		used[p][pre[p]]=used[pre[p]][p]=true;
		for(int j=0;j<n;j++)
		{
			if(vis[j])
				Max[j][p]=Max[p][j]=max(Max[j][pre[p]],lowc[p]);
			if(!vis[j]&&lowc[j]>cost[p][j])
			{
				lowc[j]=cost[p][j];
				pre[j]=p;
			}
		}
	}
	return ans;
}

int Prim(int cost[][MAXN],int n)
{
	double ans=0;
	memset(vis,false,sizeof(vis));
	memset(lowc,0,sizeof(lowc));
	vis[0]=true;
	for(int i=1;i<n;i++)
		lowc[i]=cost[0][i];
	for(int i=1;i<n;i++)
	{
		int minc=INF;
		int p=-1;
		for(int j=0;j<n;j++)
		{
			if(!vis[j]&&minc>lowc[j])
			{
				minc=lowc[j];
				p=j;
			}
		}
		if(minc==INF)
			return -1;
		ans+=minc;
		vis[p]=true;
		for(int j=0;j<n;j++)
		{
			if(!vis[j]&&lowc[j]>cost[p][j])
				lowc[j]=cost[p][j];
		}
	}
	return ans;
}

void init(int cost[][MAXN],int n)
{
	for(int i=0;i<n;i++)
		for(int j=0;j<n;j++)
		{
			if(i==j)
				cost[i][j]=0;
			else
				cost[i][j]=cost[j][i]=INF;
		}
}

int ans;

int smst(int cost[][MAXN],int n)
{
	int Min=INF;
	for(int i=0;i<n;i++)
		for(int j=i+1;j<n;j++)
		{
			if(cost[i][j]!=INF&&!used[i][j])
			{
				Min=min(Min,ans+cost[i][j]-Max[i][j]);
			}
		}
	if(Min==INF)
		return -1;
	return Min;
}

int cost[MAXN][MAXN];

int main()
{
	//freopen("in.txt","r",stdin);
	//freopen("out.txt","w",stdout);
	int T,s[MAXN];
	scanf("%d",&T);
	while(T--)
	{
		int n;
		scanf("%d",&n);
		init(cost,n);
		for(int i=0;i<n;i++)
			scanf("%d",&s[i]);
		for(int i=0;i<n;i++)
			for(int j=0;j<n;j++)
			{
				int a;
				scanf("%d",&a);
				cost[i][j]=a+s[i]+s[j];
			}
		printf("%d\n",Prim(cost,n));
	}
	return 0;
}
I -  Agri-Net 题目链接

#include <stdio.h>
#include <string.h>
#include <iostream>
#include <algorithm>
#include <vector>
#include <queue>
#include <set>
#include <map>
#include <string>
#include <math.h>
#include <stdlib.h>
#include <time.h>
using namespace std;


const int INF=0x3f3f3f3f;
const int MAXN=109;
bool vis[MAXN];
int lowc[MAXN];
int cost[MAXN][MAXN];
int n;

int Prim()
{
	int ans=0;
	memset(vis,0,sizeof(vis));
	vis[1]=true;
	for(int i=2;i<=n;i++)
	{
		lowc[i]=cost[1][i];
	}
	for(int i=2;i<=n;i++)
	{
		int minc=INF;
		int p=-1;
		for(int j=1;j<=n;j++)
		{
			if(!vis[j]&&minc>lowc[j])
			{
				minc=lowc[j];
				p=j;
			}
		}
		if(minc==INF)
			return -1;
		ans+=minc;
		vis[p]=true;
		for(int j=1;j<=n;j++)
		{
			if(!vis[j]&&lowc[j]>cost[p][j])
				lowc[j]=cost[p][j];
		}
	}
	return ans;
}

int main()
{
    //freopen("in.txt","r",stdin);
    //freopen("out.txt","w",stdout);
	while(scanf("%d",&n)==1)
	{
		for(int i=1;i<=n;i++)
			lowc[i]=i;
		for(int i=1;i<=n;i++)
			for(int j=1;j<=n;j++)
			{
				scanf("%d",&cost[i][j]);
			}
		printf("%d\n",Prim());
	}
    return 0;
}

K -  The Unique MST 题目链接

此题错了5次。。

#include <stdio.h>
#include <string.h>
#include <math.h>
#include <iostream>
#include <stdlib.h>
using namespace std;

const int INF=0x3f3f3f3f;
const int MAXN=109;
bool vis[MAXN];
int lowc[MAXN];
int pre[MAXN];
int Max[MAXN][MAXN];
bool used[MAXN][MAXN];

int prim(int cost[][MAXN],int n)
{
	int ans=0;
	memset(vis,false,sizeof(vis));
	memset(Max,0,sizeof(Max));
	memset(used,false,sizeof(used));
	vis[0]=true;
	pre[0]=-1;
	for(int i=1;i<n;i++)
	{
		lowc[i]=cost[0][i];
		pre[i]=0;
	}
	lowc[0]=0;
	for(int i=1;i<n;i++)
	{
		int minc=INF;
		int p=-1;
		for(int j=0;j<n;j++)
		{
			if(!vis[j]&&minc>lowc[j])
			{
				minc=lowc[j];
				p=j;
			}
		}
		if(minc==INF)
			return -1;
		ans+=minc;
		vis[p]=true;
		used[p][pre[p]]=used[pre[p]][p]=true;
		for(int j=0;j<n;j++)
		{
			if(vis[j])
				Max[j][p]=Max[p][j]=max(Max[j][pre[p]],lowc[p]);
			if(!vis[j]&&lowc[j]>cost[p][j])
			{
				lowc[j]=cost[p][j];
				pre[j]=p;
			}
		}
	}
	return ans;
}

int Prim(int cost[][MAXN],int n)
{
	double ans=0;
	memset(vis,false,sizeof(vis));
	memset(lowc,0,sizeof(lowc));
	vis[0]=true;
	for(int i=1;i<n;i++)
		lowc[i]=cost[0][i];
	for(int i=1;i<n;i++)
	{
		int minc=INF;
		int p=-1;
		for(int j=0;j<n;j++)
		{
			if(!vis[j]&&minc>lowc[j])
			{
				minc=lowc[j];
				p=j;
			}
		}
		if(minc==INF)
			return -1;
		ans+=minc;
		vis[p]=true;
		for(int j=0;j<n;j++)
		{
			if(!vis[j]&&lowc[j]>cost[p][j])
				lowc[j]=cost[p][j];
		}
	}
	return ans;
}

void init(int cost[][MAXN],int n)
{
	for(int i=0;i<n;i++)
		for(int j=0;j<n;j++)
		{
			if(i==j)
				cost[i][j]=0;
			else
				cost[i][j]=cost[j][i]=INF;
		}
}

int ans;

int smst(int cost[][MAXN],int n)
{
	int Min=INF;
	for(int i=0;i<n;i++)
		for(int j=i+1;j<n;j++)
		{
			if(cost[i][j]!=INF&&!used[i][j])
			{
				Min=min(Min,ans+cost[i][j]-Max[i][j]);
			}
		}
	if(Min==INF)
		return -1;
	return Min;
}

int cost[MAXN][MAXN];

int main()
{
	//freopen("in.txt","r",stdin);
	//freopen("out.txt","w",stdout);
	int T;
	scanf("%d",&T);
	while(T--)
	{
		int n,m;
		scanf("%d%d",&n,&m);
		init(cost,n);
		while(m--)
		{
			int a,b,c;
			scanf("%d%d%d",&a,&b,&c);
			cost[a-1][b-1]=cost[b-1][a-1]=c;
		}
		ans=prim(cost,n);
		if(ans==-1)
		{
			printf("Not Unique!\n");
			continue;
		}
		if(ans==smst(cost,n))
		{
			printf("Not Unique!\n");
		}
		else
		{
			printf("%d\n",ans);
		}
	}
	return 0;
}

L -  还是畅通工程 题目链接

#include <stdio.h>
#include <string.h>
#include <iostream>
#include <algorithm>
#include <vector>
#include <queue>
#include <set>
#include <map>
#include <string>
#include <math.h>
#include <stdlib.h>
#include <time.h>
using namespace std;

const int INF=0x3f3f3f3f;
const int MAXN=109;
bool vis[MAXN];
int lowc[MAXN];
int cost[MAXN][MAXN];
int n;

int Prim()
{
	int ans=0;
	memset(vis,0,sizeof(vis));
	vis[1]=true;
	for(int i=2;i<=n;i++)
	{
		lowc[i]=cost[1][i];
	}
	for(int i=2;i<=n;i++)
	{
		int minc=INF;
		int p=-1;
		for(int j=1;j<=n;j++)
		{
			if(!vis[j]&&minc>lowc[j])
			{
				minc=lowc[j];
				p=j;
			}
		}
		if(minc==INF)
			return -1;
		ans+=minc;
		vis[p]=true;
		for(int j=1;j<=n;j++)
		{
			if(!vis[j]&&lowc[j]>cost[p][j])
				lowc[j]=cost[p][j];
		}
	}
	return ans;
//	printf("%d\n",ans);
}

int main()
{
    //freopen("in.txt","r",stdin);
    //freopen("out.txt","w",stdout);
	while(scanf("%d",&n)==1)
	{
		if(n==0)
			break;
		for(int i=1;i<=n;i++)
			for(int j=1;j<=n;j++)
			{
				if(i==j)
					cost[i][j]=0;
				else
					cost[i][j]=INF;
			}
		for(int i=0;i<n*(n-1)/2;i++)
		{
			int a,b,time;
			scanf("%d%d%d",&a,&b,&time);
			if(cost[a][b]>time)
				cost[a][b]=cost[b][a]=time;
		}
		printf("%d\n",Prim());
	}
    return 0;
}

M -  Jungle Roads 题目链接

#include <stdio.h>
#include <string.h>
#include <set>
#include <map>
#include <algorithm>
#include <math.h>
#include <iostream>
using namespace std;

const int INF=0x3f3f3f3f;
const int MAXN=109;
bool vis[MAXN];
int lowc[MAXN];
int cost[109][109];


int Prim(int n)
{
	int ans=0;
	memset(vis,0,sizeof(vis));
	vis[0]=true;
	for(int i=1;i<n;i++)
		lowc[i]=cost[0][i];
	for(int i=1;i<n;i++)
	{
		int minc=INF;
		int p=-1;
		for(int j=0;j<n;j++)
		{
			if(!vis[j]&&minc>lowc[j])
			{
				minc=lowc[j];
				p=j;
			}
		}
		if(minc==INF)
			return -1;
		ans+=minc;
		vis[p]=true;
		for(int j=0;j<n;j++)
		{
			if(!vis[j]&&lowc[j]>cost[p][j])
				lowc[j]=cost[p][j];
		}
	}
	return ans;
}

void init(int n)
{
	for(int i=0;i<n;i++)
		for(int j=0;j<n;j++)
		{
			if(i==j)
				cost[i][j]=0;
			else
				cost[i][j]=cost[j][i]=INF;
		}
}

int main()
{
	int n,m,a;
	char c,d;
	while(scanf("%d",&n)==1)
	{
		if(n==0)
			break;
		getchar();
		init(n);
		for(int i=0;i<n-1;i++)
		{
			scanf("%c %d",&c,&m);
			if(m!=0)
				getchar();
			while(m--)
			{
				if(m==0)
					scanf("%c %d",&d,&a);
				else
					scanf("%c %d ",&d,&a);
				cost[c-'A'][d-'A']=cost[d-'A'][c-'A']=a;
			//	printf("%d %d \n",c-'A',d-'A');
			}
			getchar();
		}
		/*for(int i=0;i<n;i++)
		{
			for(int j=0;j<n;j++)
			{
				printf("%d ",cost[i][j]);
			}
			printf("\n");
		}*/
		printf("%d\n",Prim(n));
	}
    return 0;
}

N -  畅通工程再续 题目链接
#include <stdio.h>
#include <string.h>
#include <set>
#include <map>
#include <algorithm>
#include <math.h>
#include <iostream>
using namespace std;

const double INF=0x3f3f3f3f;
const int MAXN=109;
bool vis[MAXN];
double lowc[MAXN];
double cost[109][109];

struct node
{
	double x,y;
}s[109];

double Prim(int n)
{
	double ans=0;
	memset(vis,false,sizeof(vis));
	vis[1]=true;
	for(int i=2;i<=n;i++)
		lowc[i]=cost[1][i];
	for(int i=2;i<=n;i++)
	{
		double minc=INF;
		int p=-1;
		for(int j=1;j<=n;j++)
		{
			if(!vis[j]&&minc>lowc[j])
			{
				minc=lowc[j];
				p=j;
			}
		}
		if(minc==INF)
			return -1;
		if(minc>1000||minc<10)
		{
			return -1;
		}
		ans+=minc;
		vis[p]=true;
		for(int j=1;j<=n;j++)
		{
			if(!vis[j]&&lowc[j]>cost[p][j])
				lowc[j]=cost[p][j];
		}

	}
	return ans;
}

void init(int n)
{
	for(int i=1;i<=n;i++)
		for(int j=1;j<=n;j++)
			cost[i][j]=cost[j][i]=INF;
}

int main()
{
	int T;
	scanf("%d",&T);
	while(T--)
	{
		int n;
		scanf("%d",&n);
		for(int i=1;i<=n;i++)
		{
			scanf("%lf%lf",&s[i].x,&s[i].y);
		}
		init(n);
		int k=0;
		for(int i=1;i<=n;i++)
		{
			for(int j=i+1;j<=n;j++)
			{
				double time=sqrt((s[i].x-s[j].x)*(s[i].x-s[j].x)+(s[i].y-s[j].y)*(s[i].y-s[j].y));
				if(cost[i][j]>time&&time<=1000&&time>=10)
					cost[i][j]=cost[j][i]=time;
			}
		}
		if(Prim(n)==-1)
			printf("oh!\n");
		else
		{
			printf("%.1lf\n",Prim(n)*100.0);
		}
	}	
    return 0;
}



你可能感兴趣的:([kuangbin带你飞]专题六 最小生成树)