HDU-#1879 继续畅通工程(Prim & Kruskal)

来源:互联网 发布:北京语言大学网络教育 编辑:程序博客网 时间:2024/05/23 11:08

       题目大意:畅通工程的第n题了,这里就不再解释了。

       解题思路:很裸的一道MST,唯一需要注意的地方就是对已经修建的路径的处理,直接将其权值置为0就可以了,详见code。

       题目来源:http://acm.hdu.edu.cn/showproblem.php?pid=1879

       Prim code:

#include <iostream>#include <cstdio>#include <cstring>using namespace std;const int MAXN = 100+10;const int INF =0x3fffffff;int n,a,b,c,d;int map[MAXN][MAXN],vis[MAXN],dist[MAXN];int Prim(){    int sum=0; //各种初始化    for(int i=1;i<=n;i++) dist[i]=(i==1?0:map[1][i]);    memset(vis,0,sizeof(vis));    vis[1]=1;    for(int i=1;i<n;i++){        int pos,minn=INF;        for(int j=1;j<=n;j++) if(!vis[j] && dist[j]<minn) minn=dist[pos=j]; //寻找最短路径        vis[pos]=1;        sum+=minn; //路径求和        for(int k=1;k<=n;k++) //更新路径数组            if(!vis[k] && dist[k]>map[pos][k])                dist[k]=map[pos][k];    }    return sum;}int main(){    while(scanf("%d",&n)!=EOF && n){        for(int i=0;i<n;i++) //初始化图            for(int j=0;j<n;j++)                map[i][j]=INF;        for(int i=1;i<=n*(n-1)/2;i++){ //接收值            scanf("%d%d%d%d",&a,&b,&c,&d);            if(d==0) map[a][b]=map[b][a]=c;            else map[a][b]=map[b][a]=0; //已经修建的置为0,这样最短路径一定包含该条        }        printf("%d\n",Prim());    }    return 0;}

       再来一个Kruskal的code:

#include <iostream>#include <cstdio>#include <cstring>#include <algorithm>using namespace std;const int MAXN =100+10;int n,tmp,a,b,c,d;int p[MAXN];struct edge{    int u,v,w;}e[MAXN*MAXN];int cmp(const edge a,const edge b){return a.w<b.w;}int find(int x){return x==p[x]?x:find(p[x]);}int Kruskal(){    int ans=0;    for(int i=1;i<=n;i++) p[i]=i;    sort(e+1,e+1+tmp,cmp);    for(int i=1;i<=tmp;i++){        int x=find(e[i].u);        int y=find(e[i].v);        if(x!=y){            p[x]=y;            ans+=e[i].w;        }    }    return ans;}int main(){    while(scanf("%d",&n)!=EOF && n){        tmp=n*(n-1)/2;        for(int i=1;i<=tmp;i++){            scanf("%d%d%d%d",&a,&b,&c,&d);            if(d==0){e[i].u=a;e[i].v=b;e[i].w=c;} //唯一需要注意的地方是这里对已经修建的权值处理            else{e[i].u=a;e[i].v=b;e[i].w=0;} //当然置0就可以了        }        printf("%d\n",Kruskal());    }    return 0;}


0 0