您的位置:首页 > 其它

USACO section 3.1 Agri-Net(最小生成树,prim)

2012-10-08 21:10 399 查看
Agri-Net

RussCox

FarmerJohnhasbeenelectedmayorofhistown!Oneofhiscampaignpromiseswastobringinternetconnectivitytoallfarmsinthearea.Heneedsyourhelp,ofcourse.

FarmerJohnorderedahighspeedconnectionforhisfarmandisgoingtosharehisconnectivitywiththeotherfarmers.Tominimizecost,hewantstolaytheminimumamountofopticalfibertoconnecthisfarmtoalltheotherfarms.

Givenalistofhowmuchfiberittakestoconnecteachpairoffarms,youmustfindtheminimumamountoffiberneededtoconnectthemalltogether.Eachfarmmustconnecttosomeotherfarmsuchthatapacketcanflowfromanyonefarmtoanyotherfarm.

Thedistancebetweenanytwofarmswillnotexceed100,000.

PROGRAMNAME:agrinet

INPUTFORMAT

Line1:Thenumberoffarms,N(3<=N<=100).
Line2..end:ThesubsequentlinescontaintheNxNconnectivitymatrix,whereeachelementshowsthedistancefromonfarmtoanother.Logically,theyareNlinesofNspace-separatedintegers.Physically,theyarelimitedinlengthto80characters,sosomelines
continueontoothers.Ofcourse,thediagonalwillbe0,sincethedistancefromfarmitoitselfisnotinterestingforthisproblem.

SAMPLEINPUT(fileagrinet.in)

4
04921
40817
98016
2117160

OUTPUTFORMAT

Thesingleoutputcontainstheintegerlengththatisthesumoftheminimumlengthoffiberrequiredtoconnecttheentiresetoffarms.

SAMPLEOUTPUT(fileagrinet.out)

28


思路:没的说,典型的最小生成树,我用PRIM算法,从0开始每次加入权值最小的边,然后更新新加点的边。

或用并查集也行,每次选权最小的边,若这两点中有点不在集合中则将这边的两顶点加入集合,直到找不到符合的边

我一次过的,具体看代码:

/*
ID:nealgav1
LANG:C++
PROG:agrinet
*/
#include<fstream>
usingnamespacestd;
ifstreamcin("agrinet.in");
ofstreamcout("agrinet.out");
constintmm=210;
constintoo=1e9;
intmap[mm][mm];//记录边
intdist[mm];//记录割边距离
boolvis[mm];//标记
intm,sum;
voidprime()
{
for(inti=0;i<m;i++)
dist[i]=map[0][i];
dist[0]=oo;vis[0]=1;
inti,j,k;
for(i=1;i<m;i++)
{intmindist=oo;
for(j=0;j<m;j++)//找最小割边加入并标记
if(!vis[j]&&dist[j]<mindist)mindist=dist[j],k=j;
sum+=dist[k];vis[k]=1;
for(j=0;j<m;j++)//更新割边
if(k!=j&&dist[j]>map[k][j])dist[j]=map[k][j];
}
}
intmain()
{
cin>>m;
for(inti=0;i<m;i++)
for(intj=0;j<m;j++)
cin>>map[i][j];
sum=0;
prime();
cout<<sum<<"\n";
}

[/code]

Executing...

Test1:TESTOK[0.000secs,3528KB]

Test2:TESTOK[0.000secs,3528KB]

Test3:TESTOK[0.000secs,3528KB]

Test4:TESTOK[0.000secs,3528KB]

Test5:TESTOK[0.000secs,3528KB]

Test6:TESTOK[0.000secs,3528KB]

Test7:TESTOK[0.000secs,3528KB]

Test8:TESTOK[0.011secs,3528KB]

Test9:TESTOK[0.011secs,3528KB]

Test10:TESTOK[0.011secs,3528KB]

AlltestsOK.

YOURPROGRAM('agrinet')WORKEDFIRSTTIME!That'sfantastic

--andararething.Pleaseacceptthesespecialautomated

congratulations.

Agri-Net

RussCox
Thisproblemrequiresfindingtheminimumspanningtreeofthegivengraph.Weuseanalgorithmthat,ateachstep,lookstoaddtothespanningtreetheclosestnodenotalreadyinthetree.

Sincethetreesizesaresmallenough,wedon'tneedanycomplicateddatastructures:wejustconsidereverynodeeachtime.

#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<assert.h>

#defineMAXFARM 100

intnfarm;
intdist[MAXFARM][MAXFARM];
intisconn[MAXFARM];

void
main(void)
{
FILE*fin,*fout;
inti,j,nfarm,nnode,mindist,minnode,total;

fin=fopen("agrinet.in","r");
fout=fopen("agrinet.out","w");
assert(fin!=NULL&&fout!=NULL);

fscanf(fin,"%d",&nfarm);
for(i=0;i<nfarm;i++)
for(j=0;j<nfarm;j++)
fscanf(fin,"%d",&dist[i][j]);

total=0;
isconn[0]=1;
nnode=1;
for(isconn[0]=1,nnode=1;nnode<nfarm;nnode++){
mindist=0;
for(i=0;i<nfarm;i++)
for(j=0;j<nfarm;j++){
if(dist[i][j]&&isconn[i]&&!isconn[j]){
if(mindist==0||dist[i][j]<mindist){
mindist=dist[i][j];
minnode=j;
}
}
}
assert(mindist!=0);

isconn[minnode]=1;
total+=mindist;
}

fprintf(fout,"%d\n",total);

exit(0);
}

HereisadditionalanalysisfromAlexSchwendner:

ThesolutiongivenisO(N3);however,wecanobtainO(N2)ifwemodifyitbystoringthedistancefromeachnodeoutsideofthetreetothetreeinanarray,insteadofrecalculatingiteachtime.Thus,insteadofcheckingthedistancefromeverynodein
thetreetoeverynodeoutsideofthetreeeachtimethatweaddanodetothetree,wesimplycheckthevalueinthearrayforeachnodeoutsideofthetree.

#include<fstream.h>
#include<assert.h>

constintBIG=20000000;

intn;
intdist[1000][1000];
intdistToTree[1000];
boolinTree[1000];

main()
{
ifstreamfilein("agrinet.in");
filein>>n;
for(inti=0;i<n;++i){
for(intj=0;j<n;++j){
filein>>dist[i][j];
}
distToTree[i]=BIG;
inTree[i]=false;
}
filein.close();

intcost=0;
distToTree[0]=0;

for(inti=0;i<n;++i){
intbest=-1;
for(intj=0;j<n;++j){
if(!inTree[j]){
if(best==-1||distToTree[best]>distToTree[j]){
best=j;
}
}
}
assert(best!=-1);
assert(!inTree[best]);
assert(distToTree[best]<BIG);

inTree[best]=true;
cost+=distToTree[best];
distToTree[best]=0;
for(intj=0;j<n;++j){
if(distToTree[j]>dist[best][j]){
distToTree[j]=dist[best][j];
assert(!inTree[j]);
}
}
}
ofstreamfileout("agrinet.out");
fileout<<cost<<endl;
fileout.close();
exit(0);
}

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: