luogu P1194 买礼物

原题链接:https://www.luogu.org/problem/show?pid=1194

本题首先要注意三个地方:

第一行先输入a,再输入b,因为看反活活TLE了3次

边权为0的时候是没有优惠的,不能加边,如果边权超过a(这是个假的优惠),加边的时候加入a。

假如整张图都是0,那么就没有边读入了,然后我们就必须手动写入n-1条边。(在这里WA了两次)

结束这些后,我们就可以做裸的最小生成树了,假设买了任意的一件东西,然后就可以统计边权,最后加上一个a,作为第一件物品的价格。

#include<cstdio>
#include<algorithm>
using namespace std;
void read(int &y)
{
    y=0;char x=getchar();
    while(x<'0'||x>'9') x=getchar();
    while(x>='0'&&x<='9')
    {
        y=y*10+x-'0';
        x=getchar();
    }
}
int n,m,a,b,tot,ans,f[505];
struct edge
{
    int u,v,w;
}e[300005];
bool cmp(edge x,edge y)
{
    return x.w<y.w;
}
void add(int u,int v,int w)
{
    e[++m].u=u;
    e[m].v=v;
    e[m].w=w;
}
int find(int x)
{
    if(x==f[x]) return x;
    return f[x]=find(f[x]);
}
int main()
{
    read(a);read(n);
    for(int i=1;i<=n;i++) f[i]=i;
    for(int i=1;i<=n;i++)
    {
        for(int j=1;j<=n;j++)
        {
            read(b);
            if(i<j&&b!=0) add(i,j,min(a,b));
        }
    }
    for(int i=2;i<=n;i++) add(1,i,a);
    sort(e+1,e+m+1,cmp);
    for(int i=1;i<=m;i++)
    {
        if(find(e[i].u)!=find(e[i].v))
        {
            f[find(e[i].u)]=find(e[i].v);
            ans+=e[i].w;
            tot++;
            if(tot==n-1) break;
        }
    }
    printf("%d",ans+a);
    return 0;
}
原文地址:https://www.cnblogs.com/zeroform/p/7587471.html