附加要求的最小生成树
Problem G: YaoBIG’s country
Time Limit
Memory Limit
1 s
128 MB
Description
YaoBIG is the dominator of a big country. There are n cities (numbered from 1 to n) in his country,
and m ruined roads connecting the n cities. YaoBIG wants to repair some of the roads to make sure all his
n cities are connected. Of course,repairing a road needs some money and a road has a length. YaoBIG
can only spend P money in repairing the roads, that is to say, the total expense shouldn’t exceed P.
Meanwhile, YaoBIG doesn’t want to pass a long road. So he wants to make the longest road he repairs as
short as possible.
The question is, how much is the length of the longest road YaoBIG has to repair?
Input
The input contains zero or more test cases and the first line of the input gives the number T of test
cases. For each test case:The first line contains three positive integers n, m and P.
The next m lines give m roads. For each line, there are four positive integers ui, vi, ci and li. ui, vi
are two endpoints of the roads, ci is the cost YaoBIG has to spend if he repairs the road, and li is the
length.
Output
For each test case, output the minimum length of the longest road.
Limits
0 <= T <=10
1 <=n <=10 000
1 <=m <=100000
1 <=P <=1 000 000
1 <=ci <=100
1 <=li <=100 000
Sample Input
2
5 10 8
1 4 1 22550
4 3 1 32318
3 2 5 7448
5 1 3 19961
1 3 3 17512
4 3 4 13626
5 2 5 28227
2 4 5 26178
5 1 3 22526
5 2 2 9306
3 7 8
3 1 4 94
2 3 5 23937
1 2 3 23733
1 3 5 16994
3 2 3 4479
1 2 4 30334
1 2 2 25532
Sample Output
32318
4479
二分可能的最长长度,然后最小生成树过程中超过当前预设最大长度则不选,钱数超支或组不出树则flag置0,放宽长度条件,否则收紧长度条件。
1 #include<cstdio> 2 #include<cstring> 3 #include<algorithm> 4 #define rep(i,a,b) for(int i=a;i<=b;++i) 5 using namespace std; 6 int n,m,p,lmax,leftl,rightl,tot,cnt,flag; 7 const int MAXN=100010; 8 int father[MAXN]; 9 struct edge 10 { 11 int to; 12 int from; 13 int c; 14 int l; 15 }b[MAXN]; 16 void Input() 17 { 18 leftl=1e5;rightl=0; 19 scanf("%d%d%d",&n,&m,&p); 20 rep(i,1,m) 21 { 22 scanf("%d%d%d%d",&b[i].to,&b[i].from,&b[i].c,&b[i].l); 23 if(b[i].l<leftl) leftl=b[i].l; 24 if(b[i].l>rightl) rightl=b[i].l; 25 } 26 } 27 int findfa(int x) 28 { 29 if(father[x]!=x) father[x]=findfa(father[x]); 30 return father[x]; 31 } 32 void uni(int x,int y) 33 { 34 x=findfa(x); 35 y=findfa(y); 36 father[y]=x; 37 } 38 bool cmp(edge x,edge y) 39 { 40 return x.c<y.c; 41 } 42 void init() 43 { 44 sort(b+1,b+m+1,cmp); 45 rep(i,1,n) father[i]=i; 46 } 47 48 void Kurskal(int maxl) 49 { 50 rep(i,1,n) father[i]=i; 51 tot=0,cnt=0,flag=1; 52 rep(i,1,m) 53 { 54 if(b[i].l>maxl) continue; 55 if(findfa(b[i].to)!=findfa(b[i].from)) 56 { 57 uni(b[i].to,b[i].from); 58 tot+=b[i].c; 59 cnt++; 60 if(cnt==n-1) break; 61 } 62 } 63 if(tot>=p||cnt!=n-1) flag=0; 64 } 65 int main() 66 { 67 // freopen("in.txt","r",stdin); 68 int T; 69 scanf("%d",&T); 70 rep(k,1,T) 71 { 72 Input(); 73 init(); 74 while(leftl<rightl) 75 { 76 int mid=(leftl+rightl)>>1; 77 Kurskal(mid); 78 if(flag) rightl=mid; 79 else leftl=mid+1; 80 } 81 if(k==T) printf("%d",leftl); 82 else printf("%d\n",leftl); 83 84 } 85 return 0; 86 }