• kuangbin最小生成树专题


    网址:https://vjudge.net/contest/66965#overview

    第一题:

    poj1251

    裸最小生成树

    #include<iostream>
    #include<algorithm>
    #include<cstring>
    using namespace std;
    const int maxn=100500;
    struct node
    {
        int x;
        int y;
        int w;
    }a[maxn];
    int n,k;
    char s,v;
    int cnt;
    int w;
    int f[30];
    int  findf(int x)
    {
        if(f[x]==x)
            return x;
        else
        {
            //f[x]=findf(f[x]);
            return findf(f[x]);
        }
    }
    int join(int x,int y)
    {
        int t1=findf(x);
        int t2=findf(y);
        if(t1==t2)
            return 1;
        else
        {
            f[t2]=t1;
            return 0;
        }
    }
    int cmp(node x,node y)
    {
        return x.w<y.w;
    }
    int main()
    {
        while(cin>>n)
        {
            if(n==0)
                break;
            for(int i=1;i<=30;i++)
                f[i]=i;
            cnt=0;
            for(int i=1;i<n;i++)
            {
                cin>>s>>k;
                for(int i=1;i<=k;i++)
                {
                    cin>>v>>w;
                    a[++cnt].x=s-'A'+1;
                    a[cnt].y=v-'A'+1;
                    a[cnt].w=w;
                }
            }
            sort(a+1,a+1+cnt,cmp);
            int cot=0;
            int cost=0;
            for(int i=1;i<=cnt;i++)
            {
                if(join(a[i].x,a[i].y)==0)
                {
                    cot++;cost+=a[i].w;
                }
                if(cot==n-1)
                    break;
            }
            cout<<cost<<endl;
        }
    }
    

     

    第二题

    poj1287

    裸最小生成树

    #include<iostream>
    #include<algorithm>
    #include<cstring>
    using namespace std;
    const int maxn=100500;
    struct node
    {
        int x,y,w;
    }a[maxn];
    int f[100];
    int cnt,cot;
    int n,m;
    int x,y,w;
    bool cmp(node xx,node yy)
    {
        return xx.w<yy.w;
    }
    int findf(int u)
    {
        if(f[u]==u)
            return u;
        else
        {
            f[u]=findf(f[u]);
            return f[u];
        }
    }
    bool join(int u,int v)
    {
        int t1=findf(u);
        int t2=findf(v);
        if(t1==t2)
        {
            return false;
        }
        else
        {
            f[t2]=t1;
            return true;
        }
    }
    int main()
    {
        while(cin>>n>>m)
        {
            if(n==0)
                break;
            for(int i=1;i<=m;i++)
            {
                cin>>x>>y>>w;
                a[i].x=x;
                a[i].y=y;
                a[i].w=w;
            }
            sort(a+1,a+1+m,cmp);
            for(int i=1;i<=n;i++)
                f[i]=i;
            cnt=0;
            int cost=0;
            for(int i=1;i<=m;i++)
            {
                if(join(a[i].x,a[i].y))
                {
                    cnt++;
                    cost+=a[i].w;
                    if(cnt==n-1)
                        break;
                }
            }
            cout<<cost<<endl;
        }
    }
    

     

    第三题

    poj2031

    最小生成树+圆的距离

    #include<iostream>
    #include<algorithm>
    #include<cstring>
    #include<cmath>
    #include<cstdio>
    using namespace std;
    const int maxn=20050;
    struct node
    {
        int x,y;
        double w;
    }a[maxn];
    struct circle
    {
        double x,y,z,r;
    }c[205];
    int f[205];
    int n;
    int cnt;
    int findf(int u)
    {
        if(f[u]==u)
            return u;
        else
        {
            f[u]=findf(f[u]);
            return f[u];
        }
    }
    bool join(int u,int v)
    {
        int t1=findf(u);
        int t2=findf(v);
        if(t1==t2)
        {
            return false;
        }
        else
        {
            f[t2]=t1;
            return true;
        }
    }
    bool cmp(node u,node v)
    {
        return u.w<v.w;
    }
    double juage(int u,int v)
    {
        double tmp=sqrt((c[u].x-c[v].x)*(c[u].x-c[v].x)+(c[u].y-c[v].y)*(c[u].y-c[v].y)+(c[u].z-c[v].z)*(c[u].z-c[v].z));
        if(tmp<=(c[u].r+c[v].r))
            return 0;
        else
        {
            double ans=tmp-c[u].r-c[v].r;
            return ans;
        }
    }
    int main()
    {
        while(cin>>n)
        {
            int cot=0;
            if(n==0)
                break;
            for(int i=1;i<=n;i++)
            {
                cin>>c[i].x>>c[i].y>>c[i].z>>c[i].r;
            }
            for(int i=1;i<=n;i++)
                for(int j=1;j<=n;j++)
            {
                if(i==j)
                    continue;
                else
                {
                    a[++cot].x=i;a[cot].y=j;a[cot].w=juage(i,j);
                }
            }
            for(int i=1;i<=n;i++)
                sort(a+1,a+1+cot,cmp);
            for(int i=1;i<=n;i++)
                f[i]=i;
            cnt=0;
            double cost=0;
            for(int i=1;i<=cot;i++)
            {
                if(join(a[i].x,a[i].y))
                {
                    cost+=a[i].w;
                    cnt++;
                }
                if(cnt==n-1)
                    break;
            }
            printf("%.3f
    ",cost);
        }
    }
    

    第四题:

    poj2421

    部分边+最小生成树,先把给出的边扔进并查集里

    #include<iostream>
    #include<algorithm>
    #include<cstring>
    #include<cstdio>
    using namespace std;
    const int maxn=100500;
    struct node
    {
        int x,y,w;
    }a[maxn];
    int g[105][105];
    int n,cnt;
    int f[105];
    int cmp(node x,node y)
    {
        return x.w<y.w;
    }
    int findf(int u)
    {
        if(f[u]==u)
            return u;
        else
        {
            f[u]=findf(f[u]);
            return f[u];
        }
    }
    bool join(int u,int v)
    {
        int t1=findf(u);
        int t2=findf(v);
        if(t1==t2)
            return false;
        else
        {
            f[t2]=t1;
            return true;
        }
    }
    int main()
    {
        int x,y;
        cin>>n;
        for(int i=1;i<=n;i++)
            for(int j=1;j<=n;j++)
                cin>>g[i][j];
        int cost=0;
        int cot=0;
        for(int i=1;i<=n;i++)
            for(int j=1;j<=n;j++)
        {
            if(i==j)
                continue;
            a[++cot].x=i;a[cot].y=j;a[cot].w=g[i][j];
        }
        sort(a+1,a+1+cot,cmp);
        for(int i=1;i<=n;i++)
            f[i]=i;
        int q;
        cin>>q;
        while(q--)
        {
            cin>>x>>y;
            if(join(x,y))
            {
                cnt++;
            }
            join(x,y);
        }
        for(int i=1;i<=cot;i++)
        {
            if(cnt==n-1)
                break;
            else
            {
                if(join(a[i].x,a[i].y))
                {
                cnt++;
                cost+=a[i].w;
                }
            }
        }
        cout<<cost<<endl;
    }
    

    第五题:

    zoj1586

    用prime写的,把边权改成正常边权+点权

    #include<iostream>
    #include<algorithm>
    #include<cstring>
    #include<cstdio>
    #include<queue>
    using namespace std;
    const int maxn=1005;
    const int inf=0x3f3f3f3f;
    struct node
    {
        int num;
        int dist;
        node(int _num=0,int _dist=0):num(_num),dist(_dist){}
        friend bool operator<(node a,node b)
        {
            return a.dist>b.dist;
        }
    };
    struct Edge
    {
        int next;
        int to;
        int w;
    }edge[maxn*maxn];
    int g[maxn][maxn];
    int c[maxn];
    int n;
    int visit[maxn];
    int dist[maxn];
    int head[maxn];
    int cnt;
    void add(int u,int v,int w)
    {
        edge[cnt].next=head[u];
        edge[cnt].to=v;
        edge[cnt].w=w;
        head[u]=cnt++;
    }
    int prime(int u)
    {
        int cost=0;
        fill(dist+1,dist+1+n,inf);
        fill(visit+1,visit+1+n,0);
        dist[u]=0;
        priority_queue<node>q;
        q.push(node(u,dist[u]));
        while(!q.empty())
        {
            node x=q.top();q.pop();
            int now=x.num;
            if(visit[now])
                continue;
            visit[now]=1;
            cost+=dist[now];
            for(int i=head[now];i!=-1;i=edge[i].next)
            {
                int v=edge[i].to;
                if(visit[v])
                    continue;
                if(dist[v]>edge[i].w)
                {
                    dist[v]=edge[i].w;
                    q.push(node(v,dist[v]));
                }
            }
        }
        return cost;
    }
    void init()
    {
        memset(head,-1,sizeof(head));
        cnt=0;
    }
    int main()
    {
        int t;
        scanf("%d",&t);
        while(t--)
        {
            int start=inf;
            int pos=1;
            init();
            scanf("%d",&n);
            for(int i=1;i<=n;i++)
            {
                scanf("%d",&c[i]);
                if(start<c[i])
                {
                    start=c[i];
                    pos=i;
                }
            }
            for(int i=1;i<=n;i++)
                for(int j=1;j<=n;j++)
                scanf("%d",&g[i][j]);
            for(int i=1;i<=n;i++)
            {
                for(int j=1;j<=n;j++)
                {
                    if(i==j)
                        continue;
                    else
                    {
                        add(i,j,g[i][j]+c[i]+c[j]);
                    }
                }
            }
            int ans=prime(pos);
            cout<<ans<<endl;
        }
    }
    

    第六题

    poj1789

    裸最小生成树

    #include<iostream>
    #include<algorithm>
    #include<cstdio>
    #include<cstring>
    #include<queue>
    using namespace std;
    const int maxn=2050;
    const int inf=0x3f3f3f3f;
    struct node
    {
        int num;
        int dist;
        node(int _num=0,int _dist=0):num(_num),dist(_dist){}
        friend bool operator<(node a,node b)
        {
            return a.dist>b.dist;
        }
    };
    struct Edge
    {
        int next,to,w;
    }edge[maxn*maxn];
    int head[maxn];
    int cnt;
    int dist[maxn];
    int visit[maxn];
    int n;
    char s[maxn][10];
    void add(int u,int v,int w)
    {
        edge[cnt].next=head[u];
        edge[cnt].to=v;
        edge[cnt].w=w;
        head[u]=cnt++;
    }
    int prime(int u)
    {
        int cost=0;
        fill(dist+1,dist+1+n,inf);
        fill(visit+1,visit+1+n,0);
        dist[u]=0;
        priority_queue<node>q;
        q.push(node(u,dist[u]));
        while(!q.empty())
        {
            node x=q.top();q.pop();
            int now=x.num;
            if(visit[now])
                continue;
            visit[now]=1;
            cost+=dist[now];
            for(int i=head[now];i!=-1;i=edge[i].next)
            {
                int v=edge[i].to;
                if(visit[v])
                    continue;
                if(dist[v]>edge[i].w)
                {
                    dist[v]=edge[i].w;
                    q.push(node(v,dist[v]));
                }
            }
        }
        return cost;
    }
    int main()
    {
        while(scanf("%d",&n)!=EOF)
        {
            if(n==0)
                break;
            memset(head,-1,sizeof(head));
            cnt=0;
            int tmp;
            for(int i=1;i<=n;i++)
                scanf("%s",s[i]);
            for(int i=1;i<=n;i++)
            {
                for(int j=1;j<=n;j++)
                {
                    tmp=0;
                    if(i==j)
                        continue;
                    for(int k=0;k<7;k++)
                    {
                        if(s[i][k]!=s[j][k])
                            tmp++;
                    }
                    add(i,j,tmp);
                }
            }
            int ans=prime(1);
            printf("The highest possible quality is 1/%d.
    ",ans);
        }
    }
    

    第七题

    poj2349

    反着来,每一个s可以减少s-1条边,先处理s,然后就行了

    #include<iostream>
    #include<algorithm>
    #include<cstring>
    #include<cmath>
    #include<cstdio>
    using namespace std;
    const int maxn=505;
    struct node
    {
        int x,y;
        double w;
    }a[maxn*maxn];
    int cot,cnt;
    double ans;
    int s,p;
    double x[maxn],y[maxn];
    int f[maxn];
    int findf(int u)
    {
        if(f[u]==u)
            return u;
        else
        {
            f[u]=findf(f[u]);
            return f[u];
        }
    }
    bool join(int u,int v)
    {
        int t1=findf(u);
        int t2=findf(v);
        if(t1==t2)
        {
            return false;
        }
        else
        {
            f[t2]=t1;
            return true;
        }
    }
    bool cmp(node u,node v)
    {
        return u.w<v.w;
    }
    int tt;
    int main()
    {
        cin>>tt;
        while(tt--)
        {
            ans=cot=cnt=0;
            cin>>s>>p;
            for(int i=1;i<=p;i++)
                cin>>x[i]>>y[i];
            for(int i=1;i<=p;i++)
            {
                for(int j=1;j<=p;j++)
                {
                    if(i==j)
                        continue;
                    else
                    {
                        a[++cot].x=i;a[cot].y=j;a[cot].w=sqrt((x[i]-x[j])*(x[i]-x[j])+(y[i]-y[j])*(y[i]-y[j]));
                    }
                }
            }
            sort(a+1,a+1+cot,cmp);
            for(int i=1;i<=p;i++)
                f[i]=i;
            if(s>0)
                s--;
            for(int i=1;i<=cot;i++)
            {
                if(cnt+s>=p-1)
                    break;
                if(join(a[i].x,a[i].y))
                {
                    cnt++;
                    ans=a[i].w;
                }
            }
            printf("%.2f
    ",ans);
        }
    }
    

    第八题

    poj1751

    这道题容易超时,尽量别用浮点数,两个之间的距离可以直接用整数

    #include<iostream>
    #include<algorithm>
    #include<cstring>
    #include<cmath>
    #include<cstdio>
    using namespace std;
    const int maxn=800;
    struct node
    {
        int x,y;
        double w;
    }a[maxn*maxn];
    int cot,cnt;
    int n,k;
    int x[maxn],y[maxn];
    int f[maxn];
    int findf(int u)
    {
        if(f[u]==u)
            return u;
        else
        {
            f[u]=findf(f[u]);
            return f[u];
        }
    }
    bool join(int u,int v)
    {
        int t1=findf(u);
        int t2=findf(v);
        if(t1==t2)
        {
            return false;
        }
        else
        {
            f[t2]=t1;
            return true;
        }
    }
    bool cmp(node u,node v)
    {
        return u.w<v.w;
    }
    int tt;
    int main()
    {
        int tx,ty;
        scanf("%d",&n);
        for(int i=1;i<=n;i++)
            scanf("%d%d",&x[i],&y[i]);
        for(int i=1;i<=n;i++)
            for(int j=1;j<=n;j++)
        {
            if(i==j)
                continue;
            a[++cot].x=i;a[cot].y=j;a[cot].w=(x[i]-x[j])*(x[i]-x[j])+(y[i]-y[j])*(y[i]-y[j]);
        }
        sort(a+1,a+1+cot,cmp);
        for(int i=1;i<=n;i++)
            f[i]=i;
        int tmp=0;
        scanf("%d",&k);
        for(int i=1;i<=k;i++)
        {
            scanf("%d%d",&tx,&ty);
            if(join(tx,ty))
            {
                tmp++;
            }
            join(tx,ty);
        }
        for(int i=1;i<=cot;i++)
        {
            if(tmp+cnt>=(n-1))
                break;
            if(join(a[i].x,a[i].y))
            {
                cnt++;
                printf("%d %d
    ",a[i].x,a[i].y);
            }
        }
    }
    

    第九题:

    裸最小生成树

    #include<iostream>
    #include<algorithm>
    #include<cstring>
    #include<cmath>
    #include<cstdio>
    using namespace std;
    const int maxn=110;
    struct node
    {
        int x,y,w;
    }a[maxn*maxn];
    int cot,cnt,ans;
    int n,k;
    int x[maxn][maxn];
    int f[maxn];
    int findf(int u)
    {
        if(f[u]==u)
            return u;
        else
        {
            f[u]=findf(f[u]);
            return f[u];
        }
    }
    bool join(int u,int v)
    {
        int t1=findf(u);
        int t2=findf(v);
        if(t1==t2)
        {
            return false;
        }
        else
        {
            f[t2]=t1;
            return true;
        }
    }
    bool cmp(node u,node v)
    {
        return u.w<v.w;
    }
    int tt;
    int main()
    {
        while(scanf("%d",&n)!=EOF)
        {
            cot=ans=cnt=0;
            for(int i=1;i<=n;i++)
                for(int j=1;j<=n;j++)
                scanf("%d",&x[i][j]);
            for(int i=1;i<=n;i++)
            {
                for(int j=1;j<=n;j++)
                {
                    if(i==j)
                        continue;
                    a[++cot].x=i;a[cot].y=j;a[cot].w=x[i][j];
                }
            }
            sort(a+1,a+1+cot,cmp);
            for(int i=1;i<=n;i++)
                f[i]=i;
            for(int i=1;i<=cot;i++)
            {
                if(join(a[i].x,a[i].y))
                {
                    cnt++;
                    ans+=a[i].w;
                }
                if(cnt==n-1)
                    break;
            }
            printf("%d
    ",ans);
        }
    }
    

    第十题

    最小生成树+BFS预处理

    题意:就是每次到A,S就可以分其他路径

    注意这题有个傻逼地方,m,n输完后,n后面跟着一串空格。。这个要自己注意,我是拿gets直接输掉了

    #include<iostream>
    #include<algorithm>
    #include<cstring>
    #include<cstdio>
    #include<queue>
    using namespace std;
    const int inf=0x3f3f3f3f;
    const int maxn=100500;
    struct node
    {
        int num;
        int dist;
        node(int _num,int _dist):num(_num),dist(_dist){}
        friend bool operator<(node a,node b)
        {
            return a.dist>b.dist;
        }
    };
    struct Edge
    {
        int next,to,w;
    }edge[maxn];
    struct Node
    {
        int x,y,s;
    }que[2505];
    char s[550][550];
    int dist[2505];
    bool visit[2505];
    bool vis[550][550];
    int next[4][2]={{1,0},{0,1},{-1,0},{0,-1}};
    int n,m,cnt,Start,End;
    int head[maxn];
    void add(int u,int v,int w)
    {
        edge[cnt].next=head[u];edge[cnt].to=v;edge[cnt].w=w;head[u]=cnt++;
        edge[cnt].next=head[v];edge[cnt].to=u;edge[cnt].w=w;head[v]=cnt++;
    }
    void bfs(int st,int en)
    {
        memset(vis,0,sizeof(vis));
        int tail,head;
        int tx,ty;
        tail=head=1;
        vis[st][en]=1;
        que[tail].x=st;que[tail].y=en;que[tail].s=0;
        tail++;
        while(head<tail)
        {
            for(int i=0;i<=3;i++)
            {
                tx=que[head].x+next[i][0];
                ty=que[head].y+next[i][1];
                if(tx<1||tx>n||ty<1||ty>m)
                    continue;
                if(s[tx][ty]!='#'&&vis[tx][ty]==0)
                {
                    que[tail].x=tx;
                    que[tail].y=ty;
                    que[tail].s=que[head].s+1;
                    vis[tx][ty]=1;
                    if(s[tx][ty]=='A'||s[tx][ty]=='S')
                        add((st-1)*m+en,(tx-1)*m+ty,que[tail].s);
                    tail++;
                }
            }
            head++;
        }
    }
    int prime(int u)
    {
        memset(dist,inf,sizeof(dist));
        memset(visit,0,sizeof(visit));
        int sum=0;
        int lowcast=0;
        priority_queue<node> q;
        dist[u]=0;
        q.push(node(u,dist[u]));
        while(!q.empty())
        {
            node x=q.top();q.pop();
            int now=x.num;
            if(visit[now]==1)
                continue;
            visit[now]=1;
            sum=sum+dist[now];
            for(int i=head[now];i!=-1;i=edge[i].next)
            {
                int v=edge[i].to;
                if(visit[v]==1)
                    continue;
                if(dist[v]>edge[i].w)
                {
                    dist[v]=edge[i].w;
                    q.push(node(v,dist[v]));
                }
            }
        }
        return sum;
    }
    int main()
    {
        char ss[100];
        int T;
        cin>>T;
        while(T--)
        {
            memset(head,-1,sizeof(head));cnt=0;
            cin>>m>>n;
            gets(ss);
            for(int i=1;i<=n;i++)
                gets(s[i]+1);
            for(int i=1;i<=n;i++)
                for(int j=1;j<=m;j++)
            {
                if(s[i][j]=='S'||s[i][j]=='A')
                    bfs(i,j);
                if(s[i][j]=='S')
                    Start=i,End=j;
            }
            int ans=prime((Start-1)*n+End);
            printf("%d
    ",ans);
        }
    }
    

      

    第十一题

    poj1679

    裸次小生成树

    #include<iostream>
    #include<cstring>
    #include<cstdio>
    #include<algorithm>
    const int inf=0x3f3f3f3f;
    const int maxn=1005;
    using namespace std;
    bool visit[maxn];
    int Map[maxn][maxn];
    bool used[maxn][maxn];//两个点的那条边是否被使用过;
    int Max[maxn][maxn];//记录MST中两个点的最大距离;
    int dist[maxn];
    int pre[maxn];//保存父节点;
    int n,m;
    int prime()
    {
        int ans=0;
        memset(visit,false,sizeof(visit));
        memset(Max,0,sizeof(Max));
        memset(used,0,sizeof(used));
        visit[1]=1;pre[1]=-1;
        for(int i=2;i<=n;i++)
        {
            dist[i]=Map[1][i];
            pre[i]=1;
        }
        dist[1]=0;
        for(int i=1;i<=n-1;i++)
        {
            int lowcast=inf;
            int temp=-1;
            for(int j=1;j<=n;j++)
            {
                if(!visit[j]&&lowcast>dist[j])
                {
                    lowcast=dist[j];
                    temp=j;
                }
            }
            if(lowcast==inf)//这说明有点不连通;
                return -1;
            ans+=lowcast;//最小生成树的值;
            visit[temp]=1;
            used[temp][pre[temp]]=used[pre[temp]][temp]=1;
            for(int j=1;j<=n;j++)
            {
                if(visit[j])
                    Max[j][temp]=Max[temp][j]=max(Max[j][pre[temp]],dist[temp]);//数组的作用是记录MST里面两个点的最大距离;
                if(!visit[j]&&dist[j]>Map[temp][j])
                {
                    dist[j]=Map[temp][j];
                    pre[j]=temp;
                }
            }
        }
        return ans;
    }
    int ans;
    int SMST()
    {
        int minn=inf;
        for(int i=1;i<=n;i++)
        {
            for(int j=i+1;j<=n;j++)
            {
                if(Map[i][j]!=inf&&(!used[i][j]))
                {
                    minn=min(minn,ans+Map[i][j]-Max[i][j]);
                }
            }
        }
        if(minn==inf)
            return -1;//没有最小生成树;
        return minn;
    }
    int main()
    {
        int t;
        int x,y,w;
        cin>>t;
        while(t--)
        {
            cin>>n>>m;
            for(int i=1;i<=n;i++)
                for(int j=1;j<=n;j++)
            {
                if(i==j)
                    Map[i][j]=0;
                else
                    Map[i][j]=inf;
            }
            for(int i=1;i<=m;i++)
            {
                cin>>x>>y>>w;
                Map[x][y]=w;Map[y][x]=w;
            }
            ans=prime();
            if(ans==-1)
            {
                printf("Not Unique!
    ");
                continue;
            }
            if(ans==SMST())printf("Not Unique!
    ");
            else printf("%d
    ",ans);
    
        }
        return 0;
    }
    

      

    第十二题

    hdu1233

    裸最小生成树

    #include<iostream>
    #include<algorithm>
    #include<cstdio>
    #include<cstring>
    #include<queue>
    #define inf 0x3f3f3f3f
    #define maxn 1005000
    using namespace std;
    struct node
    {
        int num;
        int dist;
        node(int _num=0,int _dist=0):num(_num),dist(_dist){}
        friend bool operator<(node a,node b)
        {
            if(a.dist==b.dist)
                return a.num>b.num;
            return a.dist>b.dist;
        }
    };
    struct Edge
    {
        int next;
        int to;
        int w;
    }edge[maxn];
    int dist[100500];
    int cnt;
    int head[maxn];
    int visit[100500];
    void add(int u,int v,int w)
    {
        edge[cnt].next=head[u];edge[cnt].w=w;
        edge[cnt].to=v;head[u]=cnt++;
    }
    int prime(int u)
    {
        memset(dist,inf,sizeof(dist));
        memset(visit,0,sizeof(visit));
        int sum=0;
        int lowcast=0;
        priority_queue<node> q;
        dist[u]=0;
        q.push(node(u,dist[u]));
        while(!q.empty())
        {
            node x=q.top();q.pop();
            int now=x.num;
            if(visit[now]==1)
                continue;
            visit[now]=1;
            sum=sum+dist[now];
            for(int i=head[now];i!=-1;i=edge[i].next)
            {
                int v=edge[i].to;
                if(visit[v]==1)
                    continue;
                if(dist[v]>edge[i].w)
                {
                    dist[v]=edge[i].w;
                    q.push(node(v,dist[v]));
                }
            }
        }
        return sum;
    }
    int main()
    {
        int n,m;
        int x,y,w;
        while(scanf("%d",&n)&&n)
        {
            m=n*(n-1)/2;
            memset(head,-1,sizeof(head));cnt=0;
            for(int i=1;i<=m;i++)
            {
                scanf("%d%d%d",&x,&y,&w);
                add(x,y,w);add(y,x,w);
            }
        int ans=prime(1);
        printf("%d
    ",ans);
        }
    }
    

     

    第十三题

    好像和前面一样的,所以没写

    第十四题

    #include<iostream>
    #include<algorithm>
    #include<cstring>
    #include<math.h>
    #include<cstdio>
    const int inf=0x7fffffff;
    using namespace std;
    struct node
    {
        double x;
        double y;
    }a[105];
    int n;
    double Map[105][105];
    double dist[105];
    bool visit[105];
    int flag;
    double prime(int x)
    {
        memset(visit,0,sizeof(visit));
        flag=0;
        int temp=inf;
        double lowcast;
        double sum=0;
        for(int i=1;i<=n;i++)
            dist[i]=Map[x][i];
        visit[x]=1;
        for(int i=1;i<=n-1;i++)
        {
            lowcast=inf;
            for(int j=1;j<=n;j++)
            {
                if(visit[j]==0&&dist[j]<lowcast)
                {
                    temp=j;lowcast=dist[j];
                }
            }
            if(temp==inf)
            {
                flag=1;break;
            }
            visit[temp]=1;
            sum+=lowcast;
            if(dist[temp]>1000)
                flag=1;
            for(int k=1;k<=n;k++)
            {
                if(visit[k]==0&&dist[k]>Map[temp][k])
                    dist[k]=Map[temp][k];
            }
        }
        return sum;
    }
    int main()
    {
        int t;
        scanf("%d",&t);
        while(t--)
        {
            scanf("%d",&n);
            for(int i=1;i<=n;i++)
                scanf("%lf%lf",&a[i].x,&a[i].y);
            for(int i=1;i<=n;i++)
            {
                for(int j=1;j<=n;j++)
                {
                    if(i==j)
                        Map[i][j]=0;
                    else
                        Map[i][j]=inf;
                }
            }
            for(int i=1;i<=n;i++)
            {
                for(int j=i+1;j<=n;j++)
                {
                    Map[i][j]=sqrt((a[i].x-a[j].x)*(a[i].x-a[j].x)+(a[i].y-a[j].y)*(a[i].y-a[j].y));
                    Map[j][i]=sqrt((a[i].x-a[j].x)*(a[i].x-a[j].x)+(a[i].y-a[j].y)*(a[i].y-a[j].y));
                    if(Map[i][j]>1000||Map[i][j]<10)
                    {
                        Map[i][j]=inf;
                        Map[j][i]=inf;
                    }
                }
            }
            double x=prime(1);
            if(flag==1||x>=inf)
                printf("oh!
    ");
            else
                {
                    x=x*100;
                    printf("%.1lf
    ",x);
                }
        }
        return 0;
    }
    

     

      

  • 相关阅读:
    使用requests爬虫简单获取知乎问题信息
    slam介绍
    move_base 控制机器人(2)
    move_base 控制机器人(1)
    Linux 常用命令-touch
    Linux 常用命令-rmdir
    Linux 常用命令-rm
    Linux 常用命令-mkdir
    Linux 目录结构
    Linux 常用命令-pwd
  • 原文地址:https://www.cnblogs.com/huangdao/p/9971668.html
Copyright © 2020-2023  润新知