COJ 2106 road

road
难度级别: A; 编程语言:不限;运行时间限制:1000ms; 运行空间限制:131072KB; 代码长度限制:102400B
试题描述
 
某国有N个城市,这N个城市由M条双向道路连接。现在这些道路都很破旧,而政府希望开支尽量少,因此政府决定只改建这M条道路中的N-1条,这N-1条道路恰好能够构成一棵树。政府将公路分成两级:一级公路和二级公路。修建一级公路需要的费用较高,但是一级公路上的车速较快。因此政府要求在这N-1条公路中至少修建K条一级公路,其余的修建二级公路。政府希望修建费用最大的那条公路的修建费用尽量小,请帮助政府解决这个问题。
输入
第一行,三个整数N、K、M。
接下来的M行,每行四个整数a、b、c1、c2,表示在a和b之间原来有一条道路,将这条道路改建成一级公路需要的费用为c1,改建成二级公路的费用为c2。
输出
一行,一个整数,表示修建费用最大的那条公路的修建费用的最小值。
输入示例
10 4 20
3 9 6 3
1 3 4 1
5 3 10 2
8 9 8 7
6 8 8 3
7 1 3 2
4 9 9 5
10 8 9 1
2 6 9 1
6 7 9 8
2 6 2 1
3 8 9 5
3 2 9 6
1 6 10 3
5 6 3 1
2 7 6 1
7 8 6 2
10 9 2 1
7 1 10 2
输出示例
5
其他说明
对于20%的数据,1<=N<=100,1<=M<=150;
对于40%的数据,1<=N<=2000,1<=M<=5000;
对于全部的数据,1<=N<=10000,1<=M<=20000,1<=c2<=c1<=30000。

题解:在最小生成树的基础上先满足k个1,再补其他的2

 1 #include<iostream>
 2 #include<cstdio>
 3 #include<cmath>
 4 #include<algorithm>
 5 #include<queue>
 6 #include<cstring>
 7 #define PAU putchar(' ')
 8 #define ENT putchar('
')
 9 using namespace std;
10 const int maxn=10000+10,maxm=20000+10,inf=-1u>>1;
11 struct edge{int x,y,w;}e1[maxm],e2[maxm];
12 bool operator<(const edge&a,const edge&b){return a.w<b.w;}
13 int n,m,k,fa[maxn];
14 int findset(int x){return x==fa[x]?x:fa[x]=findset(fa[x]);}
15 bool check(int lim){
16     int num=0,tot=n;for(int i=1;i<=n;i++)fa[i]=i;
17     for(int i=0;i<m;i++){
18         if(e1[i].w>lim)break;
19         int f1=findset(e1[i].x),f2=findset(e1[i].y);
20         if(f1!=f2)fa[f1]=f2,num++,tot--;
21     }if(num<k)return false;
22     for(int i=0;i<m;i++){
23         if(e2[i].w>lim)break;
24         int f1=findset(e2[i].x),f2=findset(e2[i].y);
25         if(f1!=f2)fa[f1]=f2,tot--;
26     }return tot==1?true:false;
27 }
28 inline int read(){
29     int x=0,sig=1;char ch=getchar();
30     for(;!isdigit(ch);ch=getchar())if(ch=='-')sig=0;
31     for(;isdigit(ch);ch=getchar())x=10*x+ch-'0';
32     return sig?x:-x;
33 }
34 inline void write(int x){
35     if(x==0){putchar('0');return;}if(x<0)putchar('-'),x=-x;
36     int len=0,buf[15];while(x)buf[len++]=x%10,x/=10;
37     for(int i=len-1;i>=0;i--)putchar(buf[i]+'0');return;
38 }
39 void init(){
40     n=read();k=read();m=read();int x,y;
41     for(int i=0;i<m;i++)x=read(),y=read(),e1[i]=(edge){x,y,read()},e2[i]=(edge){x,y,read()};
42     sort(e1,e1+m);sort(e2,e2+m);
43     int L=1,R=30000,M;
44     while(L<R){
45         M=L+R>>1;if(check(M))R=M;else L=M+1;
46     }write(L);
47     return;
48 }
49 void work(){
50     return;
51 }
52 void print(){
53     return;
54 }
55 int main(){init();work();print();return 0;}
原文地址:https://www.cnblogs.com/chxer/p/4720687.html