hdu 1875 畅通工程再续

来源:互联网 发布:台湾电信诈骗知乎 编辑:程序博客网 时间:2024/06/03 14:17

最小生成树 ——kruscal算法和prim算法

kruscal算法
代码:

#include<cstdio>#include<algorithm>#include<cmath>using namespace std;struct Island{    int x, y;} arr[500];struct node{    int u, v;    double w;} edge[2000];int per[220];int n;bool cmp(node a,node b){    return a.w < b.w;}void init(){    for(int i=1; i<=n; ++i)    {        per[i]=i;    }}int find(int x){    if(x==per[x]) return x;    return per[x]=find(per[x]);}bool join(int x,int y){    int fx=find(x);    int fy=find(y);    if(fx!=fy)    {        per[fx]=fy;        return 1;    }    return 0;}int main(){    int T;    int i, j, k;    double x, y;    scanf("%d", &T);    while(T--)    {        scanf("%d", &n);        init();        for(i = 1; i <= n; i++)        {            scanf("%d%d", &arr[i].x, &arr[i].y);        }        k=0;        for(i = 1; i <= n; i++) //把所有路记录在node结构体中        {            for(j = i+1; j <= n; j++)            {                edge[k].u = i;                edge[k].v = j;                x = (arr[j].y-arr[i].y) * (arr[j].y-arr[i].y);                y = (arr[j].x-arr[i].x) * (arr[j].x-arr[i].x);                double temp = sqrt(x+y);                edge[k++].w = temp;            }        }        sort(edge, edge+k, cmp);        double sum = 0;        for(i = 0; i < k; i++)        {            if(edge[i].w <= 1000 && edge[i].w >= 10 && join(edge[i].u,edge[i].v))//如果两个岛的距离不符合要求就会把join(edge[i].u,edge[i].v)短路            {                sum += edge[i].w;            }        }        int cnt = 0;        bool flag = 0;        for(i = 1; i <= n; i++) //短路了就不会执行了,也就不会连接了,就只需要判断根节点的个数        {            if(i == per[i]) cnt++;            if(cnt > 1) //不等于1就还有元素(小岛)没连起来,不满足题意            {                flag = 1;                break;            }        }        if(flag) printf("oh!\n");        else            printf("%.1lf\n", sum*100);    }    return 0;}


prim算法
代码:

#include <cstdio>#include <cmath>#define INF 0x3f3f3f3fusing namespace std;struct nod{    double x, y, w;}node[105];double map[105][105], sum;int s[105], n;void set(){    double d;    for(int i = 1; i <= n; i++)    {        s[i]=0; node[i].w = INF;        for(int j = i + 1; j <= n; j++)        {            d = sqrt(pow(node[i].x-node[j].x, 2) + pow(node[i].y-node[j].y, 2));            if(d >= 10 && d <= 1000)            map[i][j] = map[j][i] = d*100;            else             map[i][j] = map[j][i] = INF;        }    }}int Prim(int m){    double min;    int t = 1;    s[m] = 1; sum=0;    for(int k = 2; k <= n; k++)    {        for(int i = 1; i <= n; i++)        if(s[i] == 0 && node[i].w > map[m][i])        node[i].w = map[m][i];        min = INF;        for(int j = 1; j <= n; j++)        if(s[j] == 0 && min > node[j].w)        {            min = node[j].w;            m = j;        }        if(s[m] == 0)        {            t++;            sum += min;            s[m] = 1;        }    }    if(t == n) return 1;    return 0;}int main(){    int t, k;    scanf("%d", &k);    while(k--)    {        scanf("%d", &n);        for(int i = 1; i <= n; i++)        scanf("%lf%lf", &node[i].x, &node[i].y);        set();        t = Prim(1);        if(t != 0)            printf("%.1lf\n", sum);        else            printf("oh!\n");    }}


原创粉丝点击