首页 > 代码库 > 组队赛第五场 组合隔板法+最小生成树预处理并查集

组队赛第五场 组合隔板法+最小生成树预处理并查集

UVALive 6434

题目链接:https://icpcarchive.ecs.baylor.edu/index.php?option=com_onlinejudge&Itemid=8&page=show_problem&problem=4445

这题正好就是大一小学期的时候好像是曦曦出的那个牛那题吧,就是要买多少块板然后正好把牛给拦完。这题也是一样,就是找最大的距离,当做隔板,依次把最大的距离去掉,最后的就是最小的了。

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<map>
#include<queue>
#include<set>
#include<cmath>
#include<bitset>
#define mem(a,b) memset(a,b,sizeof(a))
#define lson i<<1,l,mid
#define rson i<<1|1,mid+1,r
#define llson j<<1,l,mid
#define rrson j<<1|1,mid+1,r
#define INF 0x7fffffff
#define maxn 1010
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
int main()
{
    //freopen("test.txt","r",stdin);
    int t;
    scanf("%d",&t);
    for(int ii=1;ii<=t;ii++)
    {
        int n,m,i,sum=0,a[102];
        scanf("%d%d",&n,&m);
        for(i=0;i<n;i++)
            scanf("%d",a+i);
        sort(a,a+n);
        for(i=1;i<n;i++)
            a[i-1]=a[i]-a[i-1];
        sort(a,a+n-1);
        for(i=0;i<n-m;i++)
            sum+=a[i];
        printf("Case #%d: %d\n",ii,sum);
    }
    return 0;
}

UVALive 6437

题目链接:https://icpcarchive.ecs.baylor.edu/index.php?option=com_onlinejudge&Itemid=8&page=show_problem&problem=4448

这题刚开始我也没想好怎么做,因为找最小的,所以感觉和最小生成做有并。但是怎么有关的,想了好久,原来是预处理那里。先打发电站放进并查集里就行了,然后求出来的最小生成树肯定就是最小的啦。

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<map>
#include<queue>
#include<set>
#include<cmath>
#include<bitset>
#define mem(a,b) memset(a,b,sizeof(a))
#define lson i<<1,l,mid
#define rson i<<1|1,mid+1,r
#define llson j<<1,l,mid
#define rrson j<<1|1,mid+1,r
#define INF 0x7fffffff
#define maxn 1010
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
struct abc
{
    int u,v,w;
    bool operator<(const abc &a)const
    {
        return w<a.w;
    }
}a[40005];
int f[202],t,i,j,k,n,m,fa,power;
int find(int x)
{
    return x==f[x]?x:f[x]=find(f[x]);
}
int kruscal()
{
    sort(a,a+m);
    int sum=0;
    for(j=0;j<m;j++)
    {
        int x=find(a[j].u);
        int y=find(a[j].v);
        if(x!=y) sum+=a[j].w,f[y]=x;
    }
    return sum;
}
int main()
{
    //freopen("test.txt","r",stdin);
    scanf("%d",&t);
    for(i=1;i<=t;i++)
    {
        scanf("%d%d%d",&n,&m,&k);
        for(j=0;j<=n;j++)
            f[j]=j;
        scanf("%d",&fa);
        for(j=1;j<k;j++)
        {
            scanf("%d",&power);
            f[power]=fa;
        }
        for(j=0;j<m;j++)
            scanf("%d%d%d",&a[j].u,&a[j].v,&a[j].w);
        printf("Case #%d: %d\n",i,kruscal());
    }
    return 0;
}