公路修建问题游戏

    科技2024-04-12  79

    题目描述

    OI island是一个非常漂亮的岛屿,自开发以来,到这儿来旅游的人很多。然而,由于该岛屿刚刚开发不久,所以那 里的交通情况还是很糟糕。所以,OIER Association组织成立了,旨在建立OI island的交通系统。 OI island有n 个旅游景点,不妨将它们从1到n标号。现在,OIER Association需要修公路将这些景点连接起来。一条公路连接两 个景点。公路有,不妨称它们为一级公路和二级公路。一级公路上的车速快,但是修路的花费要大一些。 OIER As sociation打算修n-1条公路将这些景点连接起来(使得任意两个景点之间都会有一条路径)。为了保证公路系统的 效率, OIER Association希望在这n-1条公路之中,至少有k条(0≤k≤n-1)一级公路。OIER Association也不希望为 一条公路花费的钱。所以,他们希望在满足上述条件的情况下,花费最多的一条公路的花费尽可能的少。而你的任 务就是,在给定一些可能修建的公路的情况下,选择n-1条公路,满足上面的条件。 输入格式 第一行有三个数n(1≤n≤10000),k(0≤k≤n-1),m(n-1≤m≤20000),这些数之间用空格分开。 N和k如前所述,m表示有m对景点之间可以修公路。 以下的m-1行,每一行有4个正整数a,b,c1,c2 (1≤a,b≤n,a≠b,1≤c2≤c1≤30000) 表示在景点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

    题目分析

    首先看完题,我们会发现,这道题要求一个最小生成树,基本就是一个克鲁斯卡尔的板题,但是,仔细一看,会发现,有俩个边权,第一个边权必须要达到K,而第二个比第一个小,没有限制

    很明显,要先给第一个排序,然后,就连K条边,这样,就解决了K个一级路

    然后,可以把第二个排序,排完后,连剩下的边,然后,在执行时,求连的边最大值,然后,不就是道板题吗

    注意,边要开两倍

    #include<bits/stdc++.h> using namespace std; int n,m,k; int ans=0; int x,y,c1,c2,u1,v1; int fa[10005]; int jl; struct edge{ int u,v,val1,val2; }e[20005]; int find(int x) { if(fa[x]==x) { return x; } else { fa[x]=find(fa[x]); return fa[x]; } } bool cmp(edge x,edge y) { if(x.val1==y.val1) { return x.val2>y.val2; } else { return x.val1<y.val1; } } bool kmp(edge x,edge y) { return x.val2<y.val2; } int main() { scanf("%d %d%d",&n,&k,&m); for(int i=1;i<=n;i++) { fa[i]=i; } for(int i=1;i<m;i++) { scanf("%d %d%d %d",&x,&y,&c1,&c2); e[i].u=x; e[i].v=y; e[i].val1=c1; e[i].val2=c2; } int tot=0; sort(e+1,e+m,cmp); for(int i=1;i<m;i++) { int u=e[i].u; int v=e[i].v; int val=e[i].val1; if(find(u)!=find(v)) { fa[find(u)]=find(v); if(ans<val) { ans=val; } tot++; } if(tot==k) { break; } } sort(e+1,e+m,kmp); for(int i=1;i<m;i++) { int u=e[i].u; int v=e[i].v; int val=e[i].val2; if(find(u)!=find(v)) { fa[find(u)]=find(v); if(ans<val) { ans=val; } tot++; } if(tot==n) { break; } } printf("%d",ans); return 0; }

    跪求二分解法(详解)

    Processed: 0.011, SQL: 8