$P1194 買禮物$
阿新 • • 發佈:2019-03-23
out digi etc endif turn space www. ons 模板題
\(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 ; }
$P1194 買禮物$