BZOJ3624: [Apio2008]免费道路(最小生成树)
2018-09-19 02:44:40来源:博客园 阅读 ()
题意
题目链接
Sol
首先答案一定是一棵树
这棵树上有一些0边是必须要选的,我们先把他们找出来,如果数量$\geqslant k$显然无解
再考虑继续往里面加0的边,判断能否加到k条即可
具体做法是:
先让1在前做生成树,其中加入的0边是必须要选的
再让0边在前做生成树,这时候我们不必考虑最后能否生成一棵树,只需要考虑能否加入k条即可
我的思路:首先必选的0边是一定要统计出来的,然后一次性把剩下的所有0边都加进去,显然其中会有很多没有用,如果加入的边数量$<k$则无解,
否则考虑删除一些0边,LCT维护形成环后每个环上0边的数量,如果环上0的数量$>0$则减一,把该1边加入,否则不加入。如果总的0边数量为k,
直接不断加剩下的边,最后判断能否形成一棵树,否则0边的数量>k,证明无解。
应该是对的吧,不过打死我也不会去写的。。。。。
#include<cstdio> #include<algorithm> #define LL long long using namespace std; const int MAXN = 3 * 1e5 + 10, INF = 1e9 +10; inline int read() { char c = getchar(); int x = 0, f = 1; while(c < '0' || c > '9') {if(c == '-') f = -1; c = getchar();} while(c >= '0' && c <= '9') x = x * 10 + c - '0', c = getchar(); return x * f; } int N, M, K, num, mt, fa[MAXN]; struct Edge { int u, v, w, f; bool operator < (const Edge &rhs) const {return w > rhs.w;} }E[MAXN]; void AddEdge(int x, int y, int z) {E[++num] = (Edge) {x, y, z};} int comp(const Edge &a, const Edge &b) {return a.w < b.w;} int find(int x) {return fa[x] == x ? fa[x] : (fa[x] = find(fa[x]));} int calc() { int ans = 0; for(int i = 1; i <= num; i++) if(E[i].f) ans++; return ans; } int Kruskal(int opt) { if(opt == 1) sort(E + 1, E + num + 1); else sort(E + 1, E + num + 1, comp); for(int i = 1; i <= N; i++) fa[i] = i; int cnt = 0; if(opt == 2) for(int i = 1; i <= num; i++) if(E[i].f) fa[find(E[i].u)] = find(E[i].v), cnt++; for(int i = 1; i <= num; i++) { int x = E[i].u, y = E[i].v, w = E[i].w; int fx = find(x), fy = find(y); if(fx == fy) continue; if(opt == 1) { if(w == 0) E[i].f = 1; if((++cnt) == N - 1) return calc(); } else if(opt == 2) { cnt++; E[i].f = 1; if(cnt == K) return 1; } else if(opt == 3) { if(w == 0 && (!E[i].f)) continue; if((++cnt <= N - 1)) printf("%d %d %d\n", x, y, w); } fa[fx] = fy; } return 0; } int main() { N = read(); M = read(); K = read(); for(int i = 1; i <= M; i++) { int x = read(), y = read(), z = read(); AddEdge(x, y, z); //AddEdge(y, x, z); } if(Kruskal(1) > K) {puts("no solution"); return 0;} if(!Kruskal(2)) {puts("no soltion"); return 0;} Kruskal(3); return 0; }
标签:
版权申明:本站文章部分自网络,如有侵权,请联系:west999com@outlook.com
特别注意:本站所有转载文章言论不代表本站观点,本站所提供的摄影照片,插画,设计作品,如需使用,请与原作者联系,版权归原作者所有
- 开源Launcher - Wox 出炉了 2018-06-18
- 十个免费的Web压力测试工具 2018-06-18
- 一键部署mono 免费空间支持ASP.NET MVC 再也不担心伙食费换 2018-06-18
- 免费和开源的权限管理系统 2018-06-18
- 免费图片存储和图话【提供demo下载】 2018-06-18
IDC资讯: 主机资讯 注册资讯 托管资讯 vps资讯 网站建设
网站运营: 建站经验 策划盈利 搜索优化 网站推广 免费资源
网络编程: Asp.Net编程 Asp编程 Php编程 Xml编程 Access Mssql Mysql 其它
服务器技术: Web服务器 Ftp服务器 Mail服务器 Dns服务器 安全防护
软件技巧: 其它软件 Word Excel Powerpoint Ghost Vista QQ空间 QQ FlashGet 迅雷
网页制作: FrontPages Dreamweaver Javascript css photoshop fireworks Flash