NYOJ38 布线问题 prim算法 kruscal算法

来源:互联网 发布:编程儿童产业 编辑:程序博客网 时间:2024/05/22 15:31
/*    problem : NYOJ38 布线问题    stratege: kruscal algorithm    URL :http://acm.nyist.net/JudgeOnline/problem.php?pid=38    status :1663861006100213布线问题Accepted 76 4216C/C++05-13 21:57:42*/#include <iostream>#include <cstdio>#include <cstring>#include <cmath>#include <algorithm>using namespace std ;const int MAXN = 505 ;const int INF = 0xfffffff ;int mat[MAXN][MAXN] ;int vset[MAXN] ;int add[MAXN] ;int v, e, ans ;struct Node{    int a, b ;    int w ;};Node MST[MAXN*MAXN] ;bool cmp (const Node &t1, const Node &t2){    return t1.w < t2.w ;}void init (){    int i, k = 1 ;    int c, d, t ;    scanf ("%d%d", &v, &e) ;    for (i = 1; i <= e; i ++)    {        scanf ("%d%d%d", &c, &d, &t) ;        MST[k].a = c ;        MST[k].b = d ;        MST[k].w = t ;        k++ ;    }    for (i = 1; i <= v; i ++)    {        vset[i] = i ;        scanf ("%d", &add[i]) ;    }    sort (add+1, add+v+1) ;    sort (MST+1, MST+1+e, cmp) ;}void kruscal (){    int i, j, tag = 1 ;    int num = 1 ;    int u1, v1, sn1, sn2 ;    ans = 0 ;    while (num < v)    {        u1 = MST[tag].a ;        v1 = MST[tag].b ;        sn1 = vset[u1] ;        sn2 = vset[v1] ;        if (sn1 != sn2)        {            num ++ ;            ans += MST[tag].w ;            for (i = 1; i <= v; i ++)                if (vset[i] == sn2)                    vset[i] = sn1 ;        }        tag ++ ;    }}int main (){    int tcase ;    scanf ("%d", &tcase) ;    while (tcase --)    {        init () ;        kruscal () ;        printf ("%d\n", ans + add[1]) ;    }    return 0 ;}
/*    problem : NYOJ38 布线问题    stratege: prim algorithm    URL :http://acm.nyist.net/JudgeOnline/problem.php?pid=38    status :1663671006100213布线问题Accepted 44 1228C/C++05-13 21:28:39*/#include <iostream>#include <cstdio>#include <cstring>#include <cmath>#include <algorithm>using namespace std ;const int MAXN = 505 ;const int INF = 0xfffffff ;int mat[MAXN][MAXN] ;int lowcost[MAXN] ;int add[MAXN] ;int v, e, ans ;void init (){    int i, a, b, w ;    scanf ("%d%d", &v, &e) ;    ans = 0 ;    memset (mat, 0, sizeof(mat)) ;    memset (lowcost, 0, sizeof (lowcost)) ; //有多组,还是初始化安全点    for (i = 1; i <= e; i ++)    {        scanf ("%d%d%d", &a, &b, &w) ;        mat[a][b] = mat[b][a] = w ;    }    for (i = 1; i <= v; i ++) //找到额外外接的最少的钱        scanf ("%d", &add[i]) ;    sort (add+1, add+v+1) ;}void prim (){    int i, j ;    for (i = 2; i <= v; i ++) //初始化从1开始链接        lowcost[i] = mat[1][i] ;    for (i = 2; i <= v; i ++)    {        int min = INF, mtag ;        for (j = 1; j <= v; j ++)        {            if (lowcost[j] != 0 && lowcost[j] < min) //找到已加入节点中的最小边            {                min = lowcost[j] ;                mtag = j ;            }        }        lowcost[mtag] = 0 ; //标记为0,表示访问了,或者之间没有路        ans += min ;        for (j = 1; j <= v; j ++)        {            if (lowcost[j] && mat[mtag][j] < lowcost[j]) //更新所有已加入点的权值大小                lowcost[j] =  mat[mtag][j] ;        }    }}int main (){    int tcase ;    scanf ("%d", &tcase) ;    while (tcase --)    {        init () ;        prim () ;        printf ("%d\n", ans + add[1]) ;    }    return 0 ;}