一些生成树问题
2011-09-24 14:00
176 查看
poj2349
题意:给你平面上一些点,两点距离为边权,现给出n个点和k,n表示点数,k表示联通快数量,要求一个d,使将权值大于d的边去掉,原图划分为k个联通快,并使d最小。
结论:建立最小生成树,树中第k长边为d值,因为前k-1个可以成块
度限制最小生成树
poj1639
题意:小矮人聚会什么的,其实就是求对“park”节点有度数限制,询问最小生成树。
汪汀集训队论文。
假设我们已知度为p的最小生成树,如何推出度为p+1的最小生成树
枚举与v0(即park节点)相连的不在生成树中的边,根据环切性质,它所代替的是这个环上非与v0相连的最大边,我们统计一下费用,选取费用最小的边既是p+1的最小生成树。如何求出环上最大边?通过bfs,可以在o(v)时间内处理出当前情况下的值,最多做k次。
而初始度数可以先删去v0点求最小生成树,在每个联通快向v0点连边权最小的边。
这道题输入很讨厌,不给点的标号,而是名字,因此可以用字符串哈希,不过我用的是字母树。
题意:给你平面上一些点,两点距离为边权,现给出n个点和k,n表示点数,k表示联通快数量,要求一个d,使将权值大于d的边去掉,原图划分为k个联通快,并使d最小。
结论:建立最小生成树,树中第k长边为d值,因为前k-1个可以成块
var s,n,m,k,t:longint; x,y,b:array[1..500]of longint; l,r:array[1..250000]of longint; d:array[1..250000]of int64; procedure inf; begin assign(input,'2349.in');reset(input); assign(output,'2349.out');rewrite(output) end; procedure ouf; begin close(input);close(output) end; procedure origin; begin fillchar(x,sizeof(x),0);fillchar(y,sizeof(y),0); fillchar(l,sizeof(l),0);fillchar(r,sizeof(r),0); fillchar(d,sizeof(d),0);fillchar(b,sizeof(b),0); end; procedure qsort(ll,rr:longint); var i,j,dd,c:longint; begin i:=ll;j:=rr;dd:=d[(ll+rr)>>1]; repeat while d[i]<dd do inc(i); while dd<d[j] do dec(j); if not(i>j) then begin c:=l[i];l[i]:=l[j];l[j]:=c; c:=r[i];r[i]:=r[j];r[j]:=c; c:=d[i];d[i]:=d[j];d[j]:=c; inc(i);dec(j) end until i>j; if i<rr then qsort(i,rr); if ll<j then qsort(ll,j) end; function dist(i,j:longint):longint; begin exit(sqr(x[i]-x[j])+sqr(y[i]-y[j])) end; function find(x:longint):longint; begin if x<>b[x] then b[x]:=find(b[x]);find:=b[x] end; function init:double; var i,j,ll,rr,ans:longint; begin readln(k,n); origin; if n=k then exit(0); for i:=1 to n do readln(x[i],y[i]); m:=0; for i:=1 to n-1 do for j:=i+1 to n do begin inc(m);l[m]:=i;r[m]:=j;d[m]:=dist(i,j) end; qsort(1,m); for i:=1 to n do b[i]:=i;s:=0;ans:=0; for i:=1 to m do begin ll:=find(b[l[i]]);rr:=find(b[r[i]]); if ll<>rr then begin inc(s); if n-s=k then exit(sqrt(d[i])); b[rr]:=ll;ans:=d[i] end end; exit(sqrt(ans)) end; begin inf; readln(t); for t:=1 to t do writeln(init:0:2); ouf end.
度限制最小生成树
poj1639
题意:小矮人聚会什么的,其实就是求对“park”节点有度数限制,询问最小生成树。
汪汀集训队论文。
假设我们已知度为p的最小生成树,如何推出度为p+1的最小生成树
枚举与v0(即park节点)相连的不在生成树中的边,根据环切性质,它所代替的是这个环上非与v0相连的最大边,我们统计一下费用,选取费用最小的边既是p+1的最小生成树。如何求出环上最大边?通过bfs,可以在o(v)时间内处理出当前情况下的值,最多做k次。
而初始度数可以先删去v0点求最小生成树,在每个联通快向v0点连边权最小的边。
这道题输入很讨厌,不给点的标号,而是名字,因此可以用字符串哈希,不过我用的是字母树。
var l,r,w:array[1..3000]of longint; g:array[0..50,0..50]of longint; f:array[1..50,1..50]of boolean; v:array[1..50]of boolean; d,pre,b,st:array[1..50]of longint; next:array[0..3000,'A'..'z']of longint; sora:array[0..3000]of longint; n,s,ss,ans,k,p:longint; procedure qsort(ll,rr:longint); var i,j,ww,c:longint; begin i:=ll;j:=rr;ww:=w[(ll+rr)>>1]; repeat while w[i]<ww do inc(i); while ww<w[j] do dec(j); if not(i>j) then begin c:=w[i];w[i]:=w[j];w[j]:=c; c:=l[i];l[i]:=l[j];l[j]:=c; c:=r[i];r[i]:=r[j];r[j]:=c; inc(i);dec(j) end until i>j; if i<rr then qsort(i,rr); if ll<j then qsort(ll,j) end; function find(x:longint):longint; begin if b[x]<>x then b[x]:=find(b[x]);find:=b[x] end; procedure bfs; var h,r,i,ne:longint; begin fillchar(d,sizeof(d),0);fillchar(pre,sizeof(pre),0);fillchar(st,sizeof(st),0); h:=0;r:=0; for i:=2 to s do if f[1,i] then begin d[i]:=1; inc(r);st[r]:=i end; d[1]:=1; repeat inc(h);ne:=st[h]; for i:=2 to s do if (f[ne,i])and(d[i]=0) then begin if g[ne,i]>g[pre[ne],ne] then begin d[i]:=i;pre[i]:=ne end else d[i]:=d[ne]; inc(r);st[r]:=i end until h>=r end; procedure readit(i:longint); var k:longint; x:char; begin read(x);k:=0; while x<>' ' do begin if next[k,x]<>0 then k:=next[k,x] else begin inc(ss);next[k,x]:=ss;k:=ss end; read(x) end; if sora[k]<>0 then l[i]:=sora[k] else begin inc(s);sora[k]:=s;l[i]:=s end; read(x);k:=0; while x<>' ' do begin if next[k,x]<>0 then k:=next[k,x] else begin inc(ss);next[k,x]:=ss;k:=ss end; read(x) end; if sora[k]<>0 then r[i]:=sora[k] else begin inc(s);sora[k]:=s;r[i]:=s end; readln(w[i]); g[l[i],r[i]]:=w[i];g[r[i],l[i]]:=w[i] end; procedure origin; begin s:=1; next[0,'P']:=1;next[1,'a']:=2;next[2,'r']:=3;next[3,'k']:=4; sora[4]:=1;ss:=4 end; procedure swap(var a,b:longint); var c:longint; begin c:=a;a:=b;b:=c end; procedure init; var i,cos,min,mini,ll,rr,ne,tot:longint; begin readln(n); origin; for i:=1 to n do readit(i); qsort(1,n); for i:=1 to s do b[i]:=i; ans:=0; fillchar(f,sizeof(f),false); for i:=1 to n do begin ll:=find(l[i]);rr:=find(r[i]); if (ll<>1)and(rr<>1)and(ll<>rr) then begin ans:=ans+w[i]; b[ll]:=rr; f[l[i],r[i]]:=true;f[r[i],l[i]]:=true end end; readln(k); p:=0; fillchar(v,sizeof(v),true); for i:=1 to n do begin ll:=find(l[i]);rr:=find(r[i]); if ll>rr then swap(ll,rr); if (ll=1)and(v[rr]) then begin v[rr]:=false; ans:=ans+w[i]; f[1,r[i]]:=true;f[r[i],1]:=true; f[1,l[i]]:=true;f[l[i],1]:=true; inc(p) end end; tot:=ans; while p<k do begin bfs; min:=maxlongint;mini:=0; for i:=2 to s do if (not f[1,i])and(g[1,i]<>0) then begin ne:=d[i]; cos:=g[1,i]-g[pre[ne],ne]; if cos<min then begin min:=cos;mini:=i end end; tot:=tot+cos; f[1,mini]:=true;f[mini,1]:=true; f[d[mini],pre[d[mini]]]:=false;f[pre[d[mini]],d[mini]]:=false; inc(p); if tot<ans then ans:=tot end; writeln('Total miles driven: ',ans) end; begin init end.
相关文章推荐
- Cocos2d的字体生成软件Hiero v2.0 - Bitmap Font Tool的一些问题
- 关于打包java project项目 生成jar的一些问题
- 关于VS2005生成页面遇到的一些问题
- 生成静态库的一些问题-all_load
- powerDesigner生成sql一些常见问题解决
- 意外解决js动态生成的html代码中一些事件失效问题
- powerDesigner生成sql一些常见问题解决
- Mybatis:关于动态生成sql语句的一些问题
- Android Studio 之 导入Eclipse项目常见问题及解决方案 在将Eclipse做的Android项目成功导入Android Studio 后,启动生成,遇到一些问题,现总结如下:
- 解决itext生成嵌套PdfPtable时,格式,字体方面的一些问题
- QT下生成可执行程序的方法及一些问题解决办法:
- powerDesigner生成sql一些常见问题解决
- 使用自动生成Mipmap时遇到的一些问题
- MinGW gcc 生成动态链接库 dll 的一些问题汇总 (补充)
- MinGW gcc 生成动态链接库 dll 的一些问题汇总 (补充)
- 用 mingw 生成 ole com dll 的一些问题
- flask运行数据库生成脚本的一些问题
- 意外解决js动态生成的html代码中一些事件失效问题
- opencv3.3 级联分类器生成xml以及遇到的一些问题
- 解决dede生成静态页和动态页转换的一些问题,及火车采集入库生成动态的办法