【USACO题库】3.1.1 Agri-Net最短网络

来源:互联网 发布:iphone刷机用什么软件 编辑:程序博客网 时间:2024/05/22 13:58

【USACO题库】3.1.1 Agri-Net最短网络

题目:
农民约翰被选为他们镇的镇长!他其中一个竞选承诺就是在镇上建立起互联网,并连接到所有的农场。当然,他需要你的帮助。

约翰已经给他的农场安排了一条高速的网络线路,他想把这条线路共享给其他农场。为了用最小的消费,他想铺设最短的光纤去连接所有的农场。

你将得到一份各农场之间连接费用的列表,你必须找出能连接所有农场并所用光纤最短的方案。

每两个农场间的距离不会超过100000
输入:
第一行:农场的个数,N(3<=N<=100)。第二行..结尾:后来的行包含了一个N*N的矩阵,表示每个农场之间的距离。理论上,他们是N行,每行由N个用空格分隔的数组成,实际上,他们限制在80个字符,因此,某些行会紧接着另一些行。当然,对角线将会是0,因为不会有线路从第i个农场到它本身。输出:
只有一个输出,其中包含连接到每个农场的光纤的最小长度。
数据范围:
见题目


这几天在做图论专题,找到了这道USACO题

拿来练习一下

没想到以前的神题竟然如此之水!

就是一道最小生成树的题目,乍一看数据范围也没有什么特殊

果断prim,一次过


标程(prim):

var     a:array[0..1000000,1..3]of longint;        bz:array[1..1000]of boolean;        st,en:array[0..1000]of longint;        last:array[0..1000]of longint;        map:array[1..1000,1..1000]of longint;        dian,bian:array[0..1000]of longint;        n,m,min,i,j,k,l,s,x,y,tot,ans,len,v:longint;begin        readln(n);        for i:=1 to n do        for j:=1 to n do        begin        read(map[i,j]);        if map[i,j]<>0 then        begin                inc(len);                a[len,1]:=i;                a[len,2]:=j;                a[len,3]:=map[i,j];        end;        end;        x:=a[1,1];        inc(dian[0]);        dian[dian[0]]:=x;        ans:=0;        fillchar(bz,sizeof(bz),0);        bz[x]:=true;        while tot<n-1 do        begin                min:=maxlongint;                s:=0;                for i:=1 to len do                if not bz[a[i,2]] and (bz[a[i,1]])then                if a[i,3]<min  then                begin                        min:=a[i,3];                        s:=a[i,2];                end;                bz[s]:=true;                inc(tot);                ans:=ans+min;                inc(dian[0]);                dian[last[0]]:=x;        end;        writeln(ans);end.
当然克鲁斯卡尔也能做,而且效率更高一些

标程(kruskal):

var     a:array[0..10000,1..3]of longint;        map:array[1..100,1..100]of longint;        father:array[1..100]of longint;        n,i,j,k,l,ans,x,s,m,len,tot:longint;procedure qsort(l,r:longint);var     i,j,mid:longint;begin        i:=l;        j:=r;        mid:=a[(l+r)div 2,3];        repeat                while a[i,3]<mid do inc(i);                while a[j,3]>mid do dec(j);                if i<=j then                begin                        a[0]:=a[i];                        a[i]:=a[j];                        a[j]:=a[0];                        inc(i);                        dec(j);                end;        until i>j;        if i<r then qsort(i,r);        if l<j then qsort(l,j);end;function find(t:longint):longint;var     x:longint;begin        if father[t]=t then exit(t)        else        begin                x:=find(father[t]);                father[t]:=x;                exit(x);        end;end;begin        readln(n);        for i:=1 to n do        for j:=1 to n do        begin                read(map[i,j]);                if map[i,j]>0 then                begin                        inc(len);                        a[len,1]:=i;                        a[len,2]:=j;                        a[len,3]:=map[i,j];                end;        end;        qsort(1,len);        for i:=1 to n do                father[i]:=i;        tot:=0;        i:=1;        while tot<n-1 do        begin                j:=find(a[i,1]);                k:=find(a[i,2]);                if(j<>k)then                begin                        father[j]:=k;                        inc(tot);                        ans:=ans+a[i,3];                end;                inc(i);        end;        writeln(ans);end.