BZOJ题目传送门
洛谷题目传送门
因为一级公路的花费一定大于二级公路,那么我们当然恰好选 k k 条一级公路时是最优的。先以 c1 c 1 为关键字排序选 k k 条边,再以 c2 c 2 为关键字排序选 n−k−1 n − k − 1 条边即可。
代码:
#include
#include
#include
#include
#define N 10005
#define F inline
using namespace std;
struct edge{ int x,y,c1,c2,id,p; }ed[N<<1];
int n,m,k,p,cst,h[N],ans[N],fa[N];
F char readc(){
static char buf[100000],*l=buf,*r=buf;
if (l==r) r=(l=buf)+fread(buf,1,100000,stdin);
return l==r?EOF:*l++;
}
F int _read(){
int x=0; char ch=readc();
while (!isdigit(ch)) ch=readc();
while (isdigit(ch)) x=(x<<3)+(x<<1)+(ch^48),ch=readc();
return x;
}
F void writec(int x){ if (x>9) writec(x/10); putchar(x%10+48); }
F void _write(int x){ writec(x),puts(""); }
F void write_(int x){ writec(x),putchar(' '); }
F bool cmp1(edge a,edge b){ return a.c1bool cmp2(edge a,edge b){ return a.c2bool cmp3(edge a,edge b){ return a.idbool cmp4(int x,int y){ return ed[x].idint findfa(int x){ return x==fa[x]?x:fa[x]=findfa(fa[x]); }
int main(){
n=_read(),p=_read(),m=_read()-1;
for (int i=1,x,y,c1,c2;i<=m;i++){
x=_read(),y=_read(),c1=_read(),c2=_read();
ed[++k]=(edge){x,y,c1,c2,i};
}
for (int i=1;i<=n;i++) fa[i]=i;
sort(ed+1,ed+k+1,cmp1);
for (int i=1,q=0,x,y;qif ((x=findfa(ed[i].x))!=(y=findfa(ed[i].y)))
fa[x]=y,ans[++q]=ed[i].id,cst=max(cst,ed[i].c1),ed[i].p=1;
sort(ed+1,ed+k+1,cmp2);
for (int i=1,q=p,x,y,id;q1;i++)
if (!ed[i].p&&(x=findfa(ed[i].x))!=(y=findfa(ed[i].y)))
fa[x]=y,ans[++q]=ed[i].id,cst=max(cst,ed[i].c2),ed[i].p=2;
_write(cst);//sort(ed+1,ed+k+1,cmp3),sort(ans+1,ans+n,cmp4);
// for (int i=1;i
// write_(ans[i]),_write(ed[ans[i]].p);
}