• 题意
    • 求最小生成树与次小生成树
  • 题解
    • 因为点比较少,所以我们可以直接选择较为方便得到每队结点之间最小瓶颈路上最大边长的prim算法
  • 代码
    • #include<iostream>
      #include<cstdio>
      #include<set>
      #include<vector>
      #include<algorithm>
      #include<stack>
      #include<queue>
      #include<cmath>
      #include<string>
      #include<cstring>
      #include<cstdlib>
      #include<map>
      using namespace std;
      #define rep(i,a,n) for(int i=a;i<=n;++i)
      #define ll long long
      const ll mod = 10007;
      const int maxn = 1e6+10;
      const int INF=0x3f3f3f3f;
      int cost[1010][1010],lowc[2010],ans;
      int n,m;
      bool vis[3010];
      int Max[1010][1010];
      int pre[2020];
      bool used[1010][1010];
      
      int prim() {
      	int ans = 0;
      	memset(vis,false,sizeof(vis));
      	memset(Max,0,sizeof(Max));
      	memset(used,0,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] && j!=p)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 x[2010],y[2010],z[2010];
      
      int main() {
      	int t;
      	scanf("%d", &t);
      	while(t--) {
      		scanf("%d%d", &n, &m);
      		memset(cost,INF,sizeof(cost));
      		for(int i=0; i<m; i++) {
      			scanf("%d%d%d", &x[i],&y[i],&z[i]);
      			cost[x[i]-1][y[i]-1] = cost[y[i]-1][x[i]-1] = min(z[i], cost[x[i]-1][y[i]-1]);
      		}
      		int ans = prim();
      		int flag=1;
      		int ans1=INF;
      		rep(i,0,n-1){
      			
      			rep(j,i+1,n-1){
      				if(!used[i][j] && cost[i][j]!=INF){
      					ans1 = min(ans1,ans + cost[i][j] - Max[i][j]);
      				}
      				if(ans1==ans)
                      {
                          flag=0;
                          break;
                      }
      			}
      			if(!flag)break;
      		}
      		printf("%d %d\n", ans,ans1);
      	}
      
      	return 0;
      }	

发表评论

邮箱地址不会被公开。 必填项已用*标注