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 begin 13 i:=l;j:=r; 14 x:=a[(l+r) div 2,3]; 15 repeat 16 while a[i,3]<x do inc(i); 17 while a[j,3]>x do dec(j); 18 if i<=j then 19 begin 20 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 begin 31 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 begin 36 exit(getfat(x)=getfat(y)); 37 end; 38 procedure merge(x,y:longint);inline; 39 begin 40 c[getfat(x)]:=getfat(y); 41 end; 42 begin 43 readln(n,m); 44 for i:=1 to m do 45 begin 46 readln(a[i,1],a[i,2],a[i,3]); 47 end; 48 sort(1,m); 49 for i:=n-1 to m do 50 begin 51 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 do 55 begin 56 if tog(a[j,1],a[j,2])=false then 57 begin 58 dec(l); 59 merge(a[j,1],a[j,2]); 60 if l=1 then break; 61 end; 62 end; 63 if l=1 then 64 begin 65 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 begin 13 i:=l;j:=r; 14 x:=a[(l+r) div 2,3]; 15 repeat 16 while a[i,3]<x do inc(i); 17 while a[j,3]>x do dec(j); 18 if i<=j then 19 begin 20 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 begin 31 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 begin 36 exit(getfat(x)=getfat(y)); 37 end; 38 procedure merge(x,y:longint);inline; 39 begin 40 c[getfat(x)]:=getfat(y); 41 end; 42 function check(i:longint):boolean;inline; 43 var 44 j,l:longint; 45 begin 46 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 do 50 begin 51 if tog(a[j,1],a[j,2])=false then 52 begin 53 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 begin 61 readln(n,m); 62 for i:=1 to m do 63 begin 64 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 do 69 begin 70 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