BZOJ3714: [PA2014]Kuglarz

BZOJ3714: [PA2014]Kuglarz

题面

链接

题解

思维题

题意是问你最小花费多少可以使得知道1--N的所有数的值

而你每次可以知道L-R的值

而知道第i个数的值需要知道第1-i-1的值和1-i的值

所以你一共要知道1-0到1-n的所有值

跑最小生成树即可

#include<bits/stdc++.h>

using namespace std;

const int MAXN = 2000 + 10;

inline int read()
{
    int f=1,x=0;
    char ch;
    do
    {
        ch=getchar();
        if(ch=='-') f=-1;
    }while(ch<'0'||ch>'9');
    do
    {
        x=(x<<3)+(x<<1)+ch-'0';
        ch=getchar();
    }while(ch>='0'&&ch<='9');
    return f*x;
}

int n,m;
struct node
{
    int from;
    int to;
    int val;
    friend bool operator < (node a1,node a2)
    {
        return a1.val<a2.val;
    }
}g[MAXN * MAXN - 10];

int cnt=0;
int fa[MAXN*MAXN + 10];

inline void addedge(int a,int b,int c)
{
    ++cnt;g[cnt].from=a;g[cnt].to=b;g[cnt].val=c;return;
} 

inline int find(int x)
{
    if(x==fa[x]) return x;
    else return fa[x]=find(fa[x]);
}

long long sum=0;
int tot=0;

int main()
{
    n=read();
    for(int i=1;i<=n;i++) 
    {
        for(int j=i;j<=n;j++)
        {
            m+=1;
            int val=read();
            addedge(i-1,j,val);
        }
    }
    for(int i=1;i<=n;i++) fa[i]=i;
    sort(g+1,g+m+1);
    for(int i=1;i<=m;i++)
    {
        int u=g[i].from,v=g[i].to;
        int fu=find(u),fv=find(v);
        if(fu!=fv)
        {
            sum+=g[i].val;
            tot++;
            if(tot==n)
            {
                break;
            }
            fa[fu]=fv;
        }
    }
    cout<<sum<<endl;
} 

 

posted @ 2019-07-24 19:54  wlzs1432  阅读(122)  评论(0编辑  收藏  举报