最小生成树——局域网

题目背景

某个局域网内有n(n<=100)台计算机,由于搭建局域网时工作人员的疏忽,现在局域网内的连接形成了回路,我们知道如果局域网形成回路那么数据将不停的在回路内传输,造成网络卡的现象。因为连接计算机的网线本身不同,所以有一些连线不是很畅通,我们用f(i,j)表示i,j之间连接的畅通程度,f(i,j)值越小表示i,j之间连接越通畅,f(i,j)为0表示i,j之间无网线连接。

题目描述

需要解决回路问题,我们将除去一些连线,使得网络中没有回路,并且被除去网线的Σf(i,j)最大,请求出这个最大值。

输入格式:

第一行两个正整数n k

接下来的k行每行三个正整数i j m表示i,j两台计算机之间有网线联通,通畅程度为m。

输出格式:

一个正整数,Σf(i,j)的最大值

 

一道非常非常非常裸的同时又是非常基础的最小生成树的题,直接用prim算法。先求出总的权值的和,然后用prim累加最小权值和,前者减去后者就是最大值。

代码奉上:

#include<cstdio>
#include<iostream> 
#include<cstdlib>
#include<cmath>
#include<cstring>
using namespace std;
int a,b,c,i,j,k,l,m,n,inf=9999999,sum,max1;
int e[101][101],minn[101];
bool u[101];
int main()
{
    cin>>n>>m;
    for(i=1;i<=n;i++)
    for(j=1;j<=n;j++)
    if(i==j)
    e[i][j]=0;
    else
    e[i][j]=inf;//构造邻接矩阵 
    for(i=1;i<=m;i++)
    {
        cin>>a>>b>>c;
        e[a][b]=e[b][a]=c;
        max1+=c;//max储存所有的畅通程度 
}//读入数据并存入矩阵
    memset(minn,0x7f,sizeof(minn));
    minn[1]=0;    
    memset(u,1,sizeof(u));//初始化为True,表示所有点未被访问 
    for(i=1;i<=n;i++)
    {
        k=0;
        for(j=1;j<=n;j++)//寻找一个与已访问的点相连的权值最小的未被访问的点k 
        if(u[j] && minn[j]<minn[k])
        k=j;
        u[k]=false;//将k加入最小生成树,标记已访问 
        for(j=1;j<=n;j++)//修改与k相连的所有未被访问的点 
        if(u[j] && e[k][j]<minn[j])
        minn[j]=e[k][j];
    }
    for(i=1;i<=n;i++)
    sum+=minn[i];//累加权值 
    cout<<max1-sum;
    return 0;
}

 

posted @ 2017-04-12 17:53  长歌怀采薇  阅读(1050)  评论(3编辑  收藏  举报