首页 > 代码库 > 1083: [SCOI2005]繁忙的都市
1083: [SCOI2005]繁忙的都市
1083: [SCOI2005]繁忙的都市
Time Limit: 10 Sec Memory Limit: 162 MBSubmit: 1319 Solved: 878
[Submit][Status]
Description
城市C是一个非常繁忙的大都市,城市中的道路十分的拥挤,于是市长决定对其中的道路进行改造。城市C的道路是这样分布的:城市中有n个交叉路口,有些交叉路口之间有道路相连,两个交叉路口之间最多有一条道路相连接。这些道路是双向的,且把所有的交叉路口直接或间接的连接起来了。每条道路都有一个分值,分值越小表示这个道路越繁忙,越需要进行改造。但是市政府的资金有限,市长希望进行改造的道路越少越好,于是他提出下面的要求: 1. 改造的那些道路能够把所有的交叉路口直接或间接的连通起来。 2. 在满足要求1的情况下,改造的道路尽量少。 3. 在满足要求1、2的情况下,改造的那些道路中分值最大的道路分值尽量小。任务:作为市规划局的你,应当作出最佳的决策,选择那些道路应当被修建。
Input
第一行有两个整数n,m表示城市有n个交叉路口,m条道路。接下来m行是对每条道路的描述,u, v, c表示交叉路口u和v之间有道路相连,分值为c。(1≤n≤300,1≤c≤10000)
Output
两个整数s, max,表示你选出了几条道路,分值最大的那条道路的分值是多少。
Sample Input
4 5
1 2 3
1 4 5
2 4 7
2 3 6
3 4 8
1 2 3
1 4 5
2 4 7
2 3 6
3 4 8
Sample Output
3 6
HINT
Source
题解:解法一——先将所有的无向边从小到大排序,然后从前到后依次将当前边设为此次生成树的最大边,然后检验是否可行,假如可行,则输出+halt(O(n^2logn),在此题中显然也够用了,N<=1000都应该没大问题,本人程序112ms) 解法二——在解法一的基础上,引入二分,然后用类似的方法来验证是否可行,然后同理(这个是O(nlogn^2),实际速度将会有质的飞跃,至少可以扛到N<=8*10^4,本人程序44ms)
1 var //解法一——枚举 2 i,j,k,l,m,n:longint; 3 c:array[0..500] of longint; 4 a:array[0..30000,1..3] of longint; 5 PROCEdure swap(var x,y:longint);inline; 6 var z:longint; 7 begin 8 z:=x;x:=y;y:=z; 9 end;10 procedure sort(l,r:longint);inline;11 var i,j,x,y:longint;12 begin13 i:=l;j:=r;14 x:=a[(l+r) div 2,3];15 repeat16 while a[i,3]<x do inc(i);17 while a[j,3]>x do dec(j);18 if i<=j then19 begin20 swap(a[i,1],a[j,1]);21 swap(a[i,2],a[j,2]);22 swap(a[i,3],a[j,3]);23 inc(i);dec(j);24 end;25 until i>j;26 if l<j then sort(l,j);27 if i<r then sort(i,r);28 end;29 function getfat(x:longint):longint;inline;30 begin31 if x<>c[x] then c[x]:=getfat(c[x]);32 getfat:=c[x];33 end;34 function tog(x,y:longint):boolean;inline;35 begin36 exit(getfat(x)=getfat(y));37 end;38 procedure merge(x,y:longint);inline;39 begin40 c[getfat(x)]:=getfat(y);41 end;42 begin43 readln(n,m);44 for i:=1 to m do45 begin46 readln(a[i,1],a[i,2],a[i,3]);47 end;48 sort(1,m);49 for i:=n-1 to m do50 begin51 for j:=1 to n do c[j]:=j;52 merge(a[i,1],a[i,2]);53 l:=n-1;54 for j:=1 to i-1 do55 begin56 if tog(a[j,1],a[j,2])=false then57 begin58 dec(l);59 merge(a[j,1],a[j,2]);60 if l=1 then break;61 end;62 end;63 if l=1 then64 begin65 writeln(n-1,‘ ‘,a[i,3]);66 halt;67 end;68 end;69 end.
1 var //解法二——二分 2 i,j,k,l,m,n,r:longint; 3 c:array[0..500] of longint; 4 a:array[0..30000,1..3] of longint; 5 PROCEdure swap(var x,y:longint);inline; 6 var z:longint; 7 begin 8 z:=x;x:=y;y:=z; 9 end;10 procedure sort(l,r:longint);inline;11 var i,j,x,y:longint;12 begin13 i:=l;j:=r;14 x:=a[(l+r) div 2,3];15 repeat16 while a[i,3]<x do inc(i);17 while a[j,3]>x do dec(j);18 if i<=j then19 begin20 swap(a[i,1],a[j,1]);21 swap(a[i,2],a[j,2]);22 swap(a[i,3],a[j,3]);23 inc(i);dec(j);24 end;25 until i>j;26 if l<j then sort(l,j);27 if i<r then sort(i,r);28 end;29 function getfat(x:longint):longint;inline;30 begin31 if x<>c[x] then c[x]:=getfat(c[x]);32 getfat:=c[x];33 end;34 function tog(x,y:longint):boolean;inline;35 begin36 exit(getfat(x)=getfat(y));37 end;38 procedure merge(x,y:longint);inline;39 begin40 c[getfat(x)]:=getfat(y);41 end;42 function check(i:longint):boolean;inline;43 var44 j,l:longint;45 begin46 for j:=1 to n do c[j]:=j;47 merge(a[i,1],a[i,2]);48 l:=n-1;49 for j:=1 to i-1 do50 begin51 if tog(a[j,1],a[j,2])=false then52 begin53 dec(l);54 merge(a[j,1],a[j,2]);55 if l=1 then break;56 end;57 end;58 check:=(l=1);59 end;60 begin61 readln(n,m);62 for i:=1 to m do63 begin64 readln(a[i,1],a[i,2],a[i,3]);65 end;66 sort(1,m);67 l:=n-1;r:=m;68 while l<r do69 begin70 if check((l+r) div 2) then r:=(l+r) div 2 else l:=(l+r) div 2+1;71 end;72 writeln(n-1,‘ ‘,a[l,3]);73 end.74
1083: [SCOI2005]繁忙的都市
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。