最优布线问题


实验任务
学校有 n 台计算机,为了方便数据传输,现要将它们用数据线连接起来。两台计
算机被连接是指它们之间有数据线连接。由于计算机所处的位置不同,因此不同的两台计算
机的连接费用往往是不同的。
当然,如果将任意两台计算机都用数据线连接,费用将是相当庞大的。为了节省费用,
我们采用数据的间接传输手段,即一台计算机可以间接的通过若干台计算机(作为中转)来
实现与另一台计算机的连接。
现在由你负责连接这些计算机,你的任务是花费最小代价使任意两台计算机都连通(不
管是直接的或间接的),最后你还要说明方案是否唯一。
数据输入
第一行,一个整数 t,代表有几个测试例。
接下来一行,两个整数 n,m 1<=n<=100 0<=m<=10000)。
接下来 m 行,每行有三个整数 x y w,表示连接 x y 这两台计算机需要的费用是
w (1<=x y<=n 1<=w<=1000000)
数据保证图是连通的。
数据输出
对于每个测试例, 输出两行:
第一行,输出使任意两台计算机都连通的最小代价。
第二行,如果方案是唯一的,输出 Unique! 否则输出 Not Unique!
输入示例      输出示例
2             3
3 3         Unique!
1 2 1         6
2 3 2       Not Unique!
3 1 3
4 4

1 2 2
2 3 2
3 4 2
4 1 2


 #include<iostream>          
#include<algorithm>      
#define N 110      
#define EXIST 1   
#define USE 2  
#define NOT_EXIST 0   
using namespace std;     
struct Gmap     
{     
    long int w,circle_max;     
    int mark;     
    Gmap(){mark=NOT_EXIST;circle_max=0;}     
};    
long int Max(long int a,long int b)  
{  
    return a>b?a:b;  
}        
bool Second(long int *temp,Gmap (*g)[N],long int n)   
{  
    long int second_min=*temp+1,add,inc;  
    for(add=1;add<=n;add++)  
    {  
        for(inc=1;inc<=n;inc++)  
        {  
            if(g[add][inc].mark==EXIST&&second_min>(*temp)+g[add][inc].w-g[add][inc].circle_max)  
                second_min=(*temp)+g[add][inc].w-g[add][inc].circle_max;  
        }  
    }    
    return(second_min>*temp);  
}    
long int  G_map_prim(long int e,long int *temp,long int n,Gmap (*g)[N],long int max)        
{          
    long int add,in,edge,node,tmp;    
    long int *loweight;    
    bool *sign;  
    long int*previous;  
    tmp=n+1;           
    loweight=new long int[tmp];  
    sign=new bool[tmp];  
    previous=new long int[tmp];  
    while(tmp--)        
    {        
        loweight[tmp]=max;   
        sign[tmp]=1;  
        previous[tmp]=0;  
    }   
    in=1;  
    loweight[in]=0;  
    *temp=0;  
    edge=0;  
    for(add=1;add<=n;add++)  
    {  
        tmp=max;  
        for(node=2;node<=n;node++)  
        {  
            if(sign[node]&&loweight[node]<tmp)  
            {  
                tmp=loweight[node];  
                in=node;  
            }  
        }  
        if(previous[in]!=0)  
        {  
            g[previous[in]][in].mark=g[in][previous[in]].mark=USE;  
            for(node=1;node<=n;node++)  
            {  
                if(!sign[node]&&in!=node){  
                    g[in][node].circle_max=g[node][in].circle_max=Max(g[node][previous[in]].circle_max,g[previous[in]][in].w);   
                }  
            }  
        }  
        sign[in]=0;  
        (*temp)+=loweight[in];  
        edge++;  
        for(node=1;node<=n;node++)  
        {  
            if(sign[node]&&g[in][node].mark==EXIST&&g[in][node].w<loweight[node])  
            {  
                loweight[node]=g[in][node].w;  
                previous[node]=in;  
            }  
        }  
    }      
    if(edge==n-1||Second(temp,g,n))     
        return 1;     
        return 0;     
}        
int main()        
{               
    long int n,m,temp,M,a,b,w,max;   
    scanf("%d",&M);  
    while(M--)  
    {        
    scanf("%d%d",&n,&m);              
    temp=m;       
    Gmap g[N][N];  
    max=0;  
    while(temp--)        
    {         
        scanf("%d%d%d",&a,&b,&w);  
        if(g[a][b].mark==NOT_EXIST||g[b][a].mark==EXIST&&g[a][b].w>w)  
        {  
         g[a][b].w=g[b][a].w=w;     
         g[a][b].mark=g[b][a].mark=EXIST;  
        }  
        max+=w;  
    }                
    if (G_map_prim(m,&temp,n,g,max))printf("%d\nUnique!\n",temp);        
    else printf("%d\nNot Unique!\n",temp);        
    }        
    return 0;        
}  





  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值