bzoj 3624 贪心+Kruscal(并查集)
来源:互联网 发布:淘宝信用贷款突然没了 编辑:程序博客网 时间:2024/06/05 16:13
题意:n个点,m条无向边。共有两类边,分别是0类边和1类边,要求找出一棵最小生成树满足其中0类边恰好有K条,如果无解输出“no solution”
实际上就是一道经典的特殊的MST
跑两边Kruscal
第一遍:优先选择1类边,即在保证是树的前提下,能用1类边就用1类边,然后剩下的用0类边补全,则这些0类边是必须要选的,如果必选的0类边的数量大于K,则无解
第二遍:先加入上一次必须要选的0类边,然后在保证是树的前提下,在剩下的0类边里选取来补足K条,如果最后选择的0类边总数依旧小于K条,则无解,否则用1类边来补全最小生成树
type rec=record x,y,c:longint;end;var n,m,k,tt,tx,ty,t1:longint; i :longint; father :array[0..20010] of longint; l :array[0..100010] of rec; flag :array[0..100010] of boolean;function get_father(x:longint):longint;begin if x=father[x] then exit(x); father[x]:=get_father(father[x]); exit(father[x]);end;begin read(n,m,k); for i:=1 to n do father[i]:=i; for i:=1 to m do read(l[i].x,l[i].y,l[i].c); tt:=0; // use 1 as possible as you can for i:=1 to m do if l[i].c=1 then begin tx:=get_father(l[i].x); ty:=get_Father(l[i].y); if tx<>ty then begin father[tx]:=ty; inc(tt); if tt=n-1 then break; end; end; //find then necessary 0 for i:=1 to m do if (l[i].c=0) and (tt<n-1) then begin tx:=get_father(l[i].x); ty:=get_father(l[i].y); if tx<>ty then begin inc(t1); inc(tt); father[tx]:=ty; flag[i]:=true; if tt=n-1 then break; end; end; //you have to use t1 0 if t1>k then begin writeln('no solution');exit; end; for i:=1 to n do father[i]:=i; tt:=0; //use the necessary 0 for i:=1 to m do if flag[i] then begin tx:=get_father(l[i].x); ty:=get_father(l[i].y); if tx<>ty then begin dec(k); inc(tt); father[tx]:=ty; if tt=n-1 then break; end; end; //ensure use k 0 for i:=1 to m do if (l[i].c=0) and not flag[i] and (tt<n-1) then begin tx:=get_father(l[i].x); ty:=get_father(l[i].y); if tx<>ty then begin dec(k); inc(tt); father[tx]:=ty; flag[i]:=true; if (k=0) or (tt=n-1) then break; end; end; //the number of 0 is less than k if k>0 then begin writeln('no solution');exit; end; //find other 1 to make it complete for i:=1 to m do if (l[i].c=1) and (tt<n-1) then begin tx:=get_father(l[i].x); ty:=get_father(l[i].y); if tx<>ty then begin inc(tt); father[tx]:=ty; flag[i]:=true; if tt=n-1 then break; end; end; // for i:=1 to m do if flag[i] then writeln(l[i].x,' ',l[i].y,' ',l[i].c);end.——by Eirlys
0 0
- bzoj 3624 贪心+Kruscal(并查集)
- hdu3367(并查集+kruscal)
- bzoj 1104 贪心+并查集
- HDU 1863 畅通工程(prim,kruscal,并查集)
- hdu1863 畅通工程(kruscal && 并查集)
- hdu1875 畅通工程再续(kruscal && 并查集)
- 杭电-1863 畅通工程(并查集+Kruscal)
- 使用并查集的Kruscal方法
- 使用并查集实现Kruscal算法
- 最小生成树kruscal+并查集
- BZOJ 3624 并查集 (Kruskal)
- bzoj 1050/ codevs 1001 贪心(伪Kruscal)
- BZOJ 1050: [HAOI2006]旅行comf 贪心,并查集
- BZOJ 1854: [Scoi2010]游戏 贪心+并查集
- bzoj 1854 游戏 并查集+贪心 解题报告
- 贪心+并查集
- 贪心+并查集
- HDOJ 1233 还是畅通工程(并查集、kruscal算法 + prim)
- BOOST源码剖析
- Maven创建web项目学习,web和Java版本的修改
- Android 启动优化
- DB2中表名大小写
- Apache POI
- bzoj 3624 贪心+Kruscal(并查集)
- JAVA第二特性----继承
- java中找出奇数和偶数并按照从小到大的顺序输出
- 知乎:前端IDE 那个流行,那个好;
- Vue 跨域请求的解决办法
- mysql 触发器
- 进程描述符创建
- 【Linux基础】shell脚本
- 黑马程序员.Net培训第一期2012年2~6月(珍藏版黑马.NET第1期)