40分蒻羁求助大佬T-T
查看原帖
40分蒻羁求助大佬T-T
400760
ZYH20190341315楼主2020/12/22 11:32
#include<bits/stdc++.h>
using namespace std;
typedef struct st ak;
const int N=5e+3+10;
const int M=2e+5+10;
int e[N][N]={0};//邻接矩阵 
struct st{
	int v1,v2,w;
	st(){v1=v2=w=0;}
}s[M];
int n;
int m;//结点数 
int cmp(ak a,ak b)
{
	return a.w<b.w;
}
int find(int x,int y)
{//广搜从一个顶点出发
//从x出发能够到达y,说明x,y在一个连通分量中,return 0;
//否则 return 1; 
	int q[N]={0};
	int f=0,r=0;
	int book[N]={0};
	q[r++]=x;
	book[x]=1;
	while(f!=r)
	{
		int k=q[f++];
		for(int i=1;i<=m;i++)
		{
			if(!book[i]&&e[k][i]!=0)
			{
				book[i]=1;
				if(i==y)
				return 0;
				q[r++]=i;
			}
		}
	}
	return 1;
}
int main()
{
	int sum=0;
	int k=0;
	cin>>m>>n;//m结点数,n边数 
	for(int i=0;i<n;i++) 
	{
		int x,y,w;
		cin>>x>>y>>w;
		s[i].v1=x,s[i].v2=y,s[i].w=w;
	} 
	sort(s,s+n,cmp);//按权值从小到大排序 
	for(int i=0;i<n;i++)
	{
		int x,y,w;
		x=s[i].v1,y=s[i].v2,w=s[i].w;
		//printf("[%d,%d,%d]->\n",x,y,w);
		if(x==y)//自环 跳过 
		continue;
		if(find(x,y)==1)//判断x,y是否在一个联通分量中 
		{ 
			e[x][y]=w;
			e[y][x]=w;
			sum+=w;
		}
		else//在一个连通分量中,重边,选择权值最小的,作为边权 
		{//新权值小于原有权值 
		//更新x->y和y->x的权值 
			if(w<e[x][y])
			{
				sum-=e[x][y];
				e[x][y]=e[y][x]=w;
				sum+=w;
			}
		}
	}
	cout<<sum<<endl;
	return 0;
}
/* 
5 8
1 3 4
1 2 1
1 4 5
2 5 2
2 4 4
3 5 3
4 5 2
3 5 1
*/
/*
5 18
2 4 276
3 3 435
3 4 608
2 4 860
1 2 318
1 3 547
5 4 419
2 5 98
1 5 460
5 3 399
3 5 240
3 2 733
3 3 903
4 2 909
5 2 206
3 4 810
2 1 115
2 3 419
*/

2020/12/22 11:32
加载中...