其他分享
首页 > 其他分享> > $P1194 买礼物$

$P1194 买礼物$

作者:互联网

\(problem\)

简单的说 这是一道最小生成树的模板题(背板子就行了

然而刚看到这题 还不知道什么意思。

所以的话 考虑建边

怎么建边呢? 看到这题毫无头绪

第 i 件物品对 j 有优惠的话就建边 然后从 0 向各点连边权为a的边

inline void Add(int u,int v,int w) {
    cnt ++ ;
    edge[cnt] = node{u,v,w};
    return ;
}
    for(register int i=1;i<=b;i++)
        for(register int j=1;j<=b;j++) {
            int x = In() ;
            if(i<j and x) Add(i,j,x) ;
        }
    for(register int i=1;i<=b;i++) Add(0,i,a) ;

建完边按权值排序跑kruskal。这就AC了。

完整代码

#ifdef Dubug

#endif
#include <bits/stdc++.h>
using namespace std;
typedef long long LL ;
inline LL In() { LL res(0),f(1); register char c ;
    while(isspace(c=getchar())) ; c == '-'? f = -1 , c = getchar() : 0 ;
    while(res = (res << 1) + (res << 3) + (c & 15) , isdigit(c=getchar())) ;
    return res * f ;
}
int a,b;
struct node{
    int u,v,w;
};
const int N = 1 << 9;
node edge[N*N] ;
int fa[N<<1] ;
bool cmp (node x,node y) {
    return x.w < y.w ;
}
int cnt (0) ;
inline void Add(int u,int v,int w) {
    cnt ++ ;
    edge[cnt] = node{u,v,w};
    return ;
}
inline int find(int x) {
    return fa[x] == x ? fa[x] : fa[x] = find(fa[x]) ;
}
inline void merge(int x,int y) {
    fa[x] = fa[y] ;
    return ;
}
inline void kruskal() {
    LL ans (0) , v (0) ;
    sort(edge+1,edge+cnt+1,cmp) ;
    for(register int i=1;i<=cnt;i++) {
        int x = find(edge[i].u) , y = find(edge[i].v) ;
        if(x == y) continue ;
        ans += edge[i].w ;
        merge(x,y) ;
        if(++v == b) break ;
    }
    cout << ans << endl ;
    return ;
}
signed main() {
    a = In() , b = In() ;
    for(register int i=0;i<=b;i++) fa[i] = i ;
    for(register int i=1;i<=b;i++)
        for(register int j=1;j<=b;j++) {
            int x = In() ;
            if(i<j and x) Add(i,j,x) ;
        }
    for(register int i=1;i<=b;i++) Add(0,i,a) ;
    return kruskal() , 0 ;
}

标签:int,res,LL,long,建边,getchar,P1194,礼物
来源: https://www.cnblogs.com/qf-breeze/p/10585456.html