Description
学校的网速一直很慢,尤其是东九还搞了一个什么奇怪的登录验证软件,广大同学表示非常………不过,这次,某只大学霸因为GPA高达99.9分,所以获得了一次可以重新给校园网络布线的机会,看看能不能解决这个问题。
学校的网络布线规则非常简单。对于学校的N个栋建筑,在任意两个建筑Bi,Bj之间布置一条网线的代价为Vij。学校领导要求,任意两栋建筑之间必须是联通的,并且为了节省开支,还需满足一下两点要求:
1. 联通任意两栋建筑之间的路径有且仅有一条。
2. 建立这个网络的总代价最小(总代价定义为所有网线代价的和)。
对于第一点,举个例子,我们假设建立了 东九<->图书馆(网络连接为双向),图书馆<->西食堂,东九<->东七,东七<->西食堂的连接。当发起从东九到西食堂的信息传输时,信息需要决定到底是走“东九->图书馆->西食堂”这条路径,还是”东九->东七->西食堂”这条路径,这是非常麻烦的事情。所以要求联通任意两栋建筑之间的路径有且仅有一条.
因为大学霸平常刷期末考试题去了,对于这样的编程问题感到异常头疼,于是,这个问题只有看你了…..
Input
第0行:一个数T,代表一共有T组数据。
每组数据的格式:
第1行:1个正整数N,代表有N个建筑
第2..N+1行:每行N个整数Vij,第j个数字代表建立从i建筑到j建筑网线的代价。Output
第1..T*C行:一个整数,代表最小的代价
不同组数据之间没有空行。Sample Input
2
3
0 1 4
1 0 2
4 2 0
4
0 4 9 21
4 0 8 17
9 8 0 16
21 17 16 0
Sample Output
3
28
Hint
1 <= N <=100。这是一道水题。
这道题没有时间了,所以答案没有AC,但大体上应当是对的,就是一个生成最大连通图的算法。代码如下
其中32000表示无穷大
#include<stdio.h>
#include<stdlib.h>
int main(){
int i,j,t,l,n,x,y,k,p,q,templ,tt,v[100][100],m[100];
scanf("%d\n",&t);
for(l=0;l<t;l++){
scanf("%d",&n);
for(i=0;i<n;i++)
{ for(j=0;j<n;j++)
{scanf("%d",v[i]+j); }}
for(i=0;i<n;i++)
for(j=i;j<n;j++)v[i][j]=32000;
tt=0;
for(k=0;k<n;){
templ=32000;
for(i=0;i<n;i++)for(j=0;j<n;j++){
if(v[i][j]<templ){
templ=v[i][j];
p=i;q=j;
}}
y=0;
for(x=0;x<k;x++){
if(m[x]==p)y=y+1;
if(m[x]==q)y=y+2;
}
if(y==3){
v[p][q]=32000;
}else if(y==2){tt=tt+v[p][q];
v[p][q]=32000;
m[k]=p;
k++;
}else if(y==1){tt=tt+v[p][q];
v[p][q]=32000;
m[k]=q;
k++;
}else if(y==0){tt=tt+v[p][q];
v[p][q]=32000;
m[k]=p;
k=k+1;
m[k]=q;
k++;
}
}
printf("%d\n",tt);
}
system("PAUSE");
return 0;
}