【NOIP2015 Simulation 10.22】Minimum Cost

foreword

Originally, I thought of the minimum spanning tree in the competition, but I didn't believe that this problem was so simple, and then there was no such thing. . .

topic

Give an undirected weighted graph consisting of n points and m edges.
Some of the dots are black and others are white.
Now each white point must be connected to the nearest black point through the shortest path (if there are many black points, any one of them can be selected), we want to minimize the cost. What is the minimum cost please?
Note: The last selected edge ensures that the distance from each white point to the nearest black point is still equal to the shortest distance in the original image.

analyze

这道题最麻烦的地方就是最终搞成的图有可能有很多个联通块。

Add a point: 0 point, let 0 point connect all the black points, and the edge weight is 0;
process the shortest distance from S to each point The
problem requires the minimum total distance, obviously it is enough to do the minimum spanning tree once.

#include <cmath>
#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <algorithm>
#include <queue>
const long long maxlongint=2147483747;
using namespace std;
long long b[710000][4],dis[710000],next[710000],last[710000],a[710000],fa[710000],ans,tot,n,m,v[710000],d[8000000];
bool bz[710000];
void q(long long l,long long r)
{
    long long i=l,j=r;
    long long mid=b[(l+r)/2][0],e;
    while(i<j)
    {
        while(b[i][0]<mid) i++;
        while(b[j][0]>mid) j--;
        if(i<=j)
        {
            e=b[i][0];
            b[i][0]=b[j][0];
            b[j][0]=e;
            e=b[i][1];
            b[i][1]=b[j][1];
            b[j][1]=e;
            e=b[i][2];
            b[i][2]=b[j][2];
            b[j][2]=e;
            i++;
            j--;
        }
    }
    if(i<r) q(i,r);
    if(l<j) q(l,j);
}
int spfa()
{
    long long head=0,tail=1,k;
    fill(dis,dis+n+m+1,maxlongint*3);
    fill(bz,bz+n+m+1,true);
    d[1]=0;
    dis[0]=0;
    while(head<tail)
    {
        k=d[++head];
        bz[k]=true;
        for(long long i=last[k];i;i=next[i])
        {
            if(dis[a[i]]>dis[k]+v[i])
            {
                dis[a[i]]=dis[k]+v[i];
                if(bz[a[i]])
                {
                    d[++tail]=a[i];
                    bz[a[i]]=false;
                }
            }
        }
    }
}
bool dg(long long x)
{
    long long i,j;
    for(i=last[x];i;i=next[i])
    {
        long long y=a[i];
        if(dis[x]+v[i]==dis[y])
        {
            dg(y);
            b[++tot][1]=x;
            b[tot][2]=y;
            b[tot][0]=v[i];
        }
    }
    return true;
}
long long get(long long x)
{
    if(x==fa[x]) return x;
    long long y=get(fa[x]);
    fa[x]=y;
    return y;
}
int kruskal()
{
    long long i,j,k,l,x,y;
    for(i=1;i<=tot;i++)
    {
        x=get(b[i][1]);
        y=get(b[i][2]);
        if(x!=y)
        {
            ans+=b[i][0];
            fa[y]=x;
        }
    }
}
int bj(long long x,long long y,long long k)
{
    fa[y]=y;
    next[++tot]=last[x];
    last[x]=tot;
    v[tot]=k;
    a[tot]=y;
}
int main()
{
    scanf("%lld%lld",&n,&m);
    long long i,j,k,l,x,y;
    for(i=1;i<=n;i++)
    {
        scanf("%lld",&x);
        if(x) bj(0,i,0);
    }
    for(i=1;i<=m;i++)
    {
        scanf("%lld%lld%lld",&x,&y,&k);
        bj(x,y,k);
        bj(y,x,k);
    }
    spfa();
    tot=0;
    dg(0);
    q(1,tot);
    bool b1=maxlongint;
    kruskal();
    if(ans==0) cout<<"impossible";else
        cout<<ans;
}

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=325830217&siteId=291194637