• 最小生成树裸(点密)——[Usaco2007 Dec]Building Roads 修建道路


    sqrt(1000000*1000000)数据发生超int处理办法,sqrt(1.0*1000000*1000000)即可

    prim不超时

    View Code
    #include<cmath>
    #include
    <stdio.h>
    #include
    <iostream>
    #include
    <algorithm>
    using namespace std;
    #define MAX 0x3fffffff
    int n,m;

    struct data
    {
    int x,y;
    }a[
    1009];

    double map[1009][1009];
    bool use[1009];
    double dis[1009];

    void prim()
    {
    int i,j,rj;
    double add=0,min;
    for(i=1;i<=n;i++)
    {
    use[i]
    =0;
    dis[i]
    =map[1][i];
    }
    use[
    1]=1;

    for(i=1;i<n;i++)
    {
    min
    =MAX;
    for(j=1;j<=n;j++)
    {
    if(use[j]==1)continue;
    if(dis[j]<min)
    {
    min
    =dis[j];
    rj
    =j;
    }
    }
    add
    +=min;
    use[rj]
    =1;

    for(j=1;j<=n;j++)
    {
    if(use[j]==1)continue;
    if(dis[j]>map[rj][j])
    dis[j]
    =map[rj][j];
    }
    }

    printf(
    "%.2lf\n",add);
    }

    int main()
    {

    while(scanf("%d%d",&n,&m)!=EOF)
    {
    int i,j;
    for(i=1;i<=n;i++)
    {
    scanf(
    "%d%d",&a[i].x,&a[i].y);
    }

    for(i=1;i<=n;i++)
    {
    for(j=1;j<=i;j++)
    {
    if(i==j)
    {
    map[i][j]
    =MAX;
    }
    else
    {
    map[i][j]
    =sqrt(1.0*(a[i].x-a[j].x)*(a[i].x-a[j].x)+1.0*(a[i].y-a[j].y)*(a[i].y-a[j].y));//不然int会爆掉1000000*1000000
    map[j][i]=map[i][j];
    }

    }
    }

    int a,b;
    for(i=1;i<=m;i++)
    {
    scanf(
    "%d%d",&a,&b);
    map[a][b]
    =0;
    map[b][a]
    =0;
    }

    prim();
    }
    return 0;
    }

    krus() 用G++提交double 要用 .f% 刚卡进

    View Code
    #include<cmath>
    #include
    <stdio.h>
    #include
    <iostream>
    #include
    <algorithm>
    using namespace std;

    int add;
    int f[1009];

    struct data
    {
    int x,y;
    }a[
    1009];

    struct data1
    {
    int p1,p2;
    double dis;
    }dd[
    1000009];

    int find(int pos)
    {
    if(f[pos]==-1)return pos;
    return f[pos]=find(f[pos]);
    }

    int un(int a,int b)
    {
    int fa=find(a);
    int fb=find(b);
    if(fa==fb)return 0;
    f[fa]
    =fb;return 1;
    }

    bool cmp(data1 a,data1 b)
    {
    return a.dis<b.dis;
    }

    void krus()
    {
    sort(
    &dd[1],&dd[add],cmp);

    int i;
    double dall=0;
    for(i=1;i<=add-1;i++)
    {
    if(un(dd[i].p1,dd[i].p2)==1)
    dall
    +=dd[i].dis;
    }

    printf(
    "%.2lf\n",dall);
    }

    int main()
    {
    int n,m;
    while(scanf("%d%d",&n,&m)!=EOF)
    {
    int i,j;
    for(i=1;i<=n;i++)
    {
    scanf(
    "%d%d",&a[i].x,&a[i].y);
    f[i]
    =-1;
    }

    add
    =1;
    for(i=1;i<=n;i++)
    {
    for(j=1;j<=n;j++)
    {
    dd[add].p1
    =i;
    dd[add].p2
    =j;
    if(i==j)
    {
    dd[add].dis
    =0;
    }
    else
    {
    dd[add].dis
    =sqrt(1.0*(a[i].x-a[j].x)*(a[i].x-a[j].x)+1.0*(a[i].y-a[j].y)*(a[i].y-a[j].y));//????int??????1000000*1000000
    }

    add
    ++;
    }
    }

    int a,b;
    for(i=1;i<=m;i++)
    {
    scanf(
    "%d%d",&a,&b);
    un(a,b);
    }
    krus();
    }
    return 0;
    }

  • 相关阅读:
    1002. 查找常用字符
    1047. 删除字符串中的所有相邻重复项
    3. 无重复字符的最长子串
    剑指 Offer 57
    239. 滑动窗口最大值
    476. 数字的补数
    876. 链表的中间结点
    973. 最接近原点的 K 个点
    面试题 02.04. 分割链表
    1616. 分割两个字符串得到回文串
  • 原文地址:https://www.cnblogs.com/huhuuu/p/1987448.html
Copyright © 2020-2023  润新知