road |
难度级别: A; 编程语言:不限;运行时间限制:1000ms; 运行空间限制:131072KB; 代码长度限制:102400B |
试题描述
|
|
输入
|
第一行,三个整数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;}