买礼物
2017-10-26 23:20
141 查看
原题链接:https://www.luogu.org/problem/show?pid=1194#sub
日常数组开小(1/1)。
一个裸的最小生成树。跑一遍最小生成树记录一下所花价钱,然后扫一下father数组把没优惠的补上,输出就好了。
参考代码:
#include <iostream> #include <cstring> #include <cstdio> #include <algorithm> #define maxn 500000 using namespace std; struct Edge{ int from,to,dis; bool operator<(const Edge &rhs)const{ return dis < rhs.dis; } }; inline int read(){ int num = 0; char c; bool flag = false; while ((c = getchar()) == ' ' || c == '\n' || c == '\r'); if (c == '-') flag = true; else num = c - '0'; while (isdigit(c = getchar())) num = num * 10 + c - '0'; return (flag ? -1 : 1) * num; } Edge edge[maxn]; int father[maxn]; int n,m; int tot = 0; int ans,totedge,readnum; int find(int x){ if (father[x] == x) return father[x]; else return find(father[x]); } void merge(int x,int y){ father[find(y)] = find(x); } bool check(int x,int y){ return find(x) == find(y); } int main(){ n = read();m = read(); for (register int i=1;i<=m;i++) father[i] = i; for (register int i=1;i<=m;i++) for (register int j=1;j<=m;j++){ readnum = read(); if (readnum!=0){ edge[++tot].from = i; edge[tot].to = j; edge[tot].dis = readnum; } } sort(edge+1,edge+tot+1); for (register int i=1;i<=tot;i++){ int u = edge[i].from; int v = edge[i].to; if (!check(u,v)){ totedge++; ans += edge[i].dis; merge(u,v); if (totedge == m-1) break; } } for (register int i=1;i<=n;i++) if (father[i] == i) ans += n; printf("%d\n",ans); return 0; }
相关文章推荐
- ccBoy 的.NET开发人员资源列表 V1.5 – 送给.NET开发人员的礼物
- 情人节小礼物
- 莫名的礼物
- 送给程序员的一份礼物——常用工具集(转载)
- Sun 在圣诞节前送出的最后礼物-NetBeans 5.5多国语言版释出!
- 情人节最好的礼物-网卡Lan91C111调试手记
- 礼物
- 男女朋友之间送礼物的含义
- 小人儿的礼物
- 收到的礼物——微软蓝牙无线鼠标5000
- 11月11日大师献给各位染成茜色的坂道FANS的礼物—— あかね色に染まる坂是怎么破解的?
- 谢谢晶晶送的开张礼物
- 2009年母亲节礼物:你准备好了吗?
- 医生的喜欢的礼物!
- 男女之间互送礼物的含义大全 别送错了
- 正则表达式!为.Net开发者献上的小礼物
- 邀请你加入“魔教”微群 -- 有个小礼物给朋友们
- 《Excel图表之道》礼物下载
- 给朋友结婚时的礼物
- 【转】20岁的万维网带给我们的20件礼物(图)