1 条题解
-
0
自动搬运
来自洛谷,原作者为

D10s
**搬运于
2025-08-24 21:41:44,当前版本为作者最后更新于2017-10-31 10:00:49,作者可能在搬运后再次修改,您可在原文处查看最新版自动搬运只会搬运当前题目点赞数最高的题解,您可前往洛谷题解查看更多
以下是正文
本题也可采取图论做法,相当于是双边权情况下的最小生成树。
因为题目保证t<T,所以边权取T的边不可能超过k条(超过的拿t替换更优)。
这样我们只要在克鲁斯卡尔的时候前k条边用T扩展,后n-1-k条用t即可,记录最大边权。
#include<cstdio> #include<queue> using namespace std; struct edge{ int u,v,t,T; }e; struct cmp1{bool operator () (edge a,edge b) {return a.t>b.t;} }; struct cmp2{bool operator () (edge a,edge b) {return a.T>b.T;} }; priority_queue<edge,vector<edge>,cmp1> q1; priority_queue<edge,vector<edge>,cmp2> q2; int fa[10005]; int find(int x) {return fa[x]==x?x:fa[x]=find(fa[x]);} int max(int x,int y) {return x>y?x:y;} int main() { int n,m,k; scanf("%d%d%d",&n,&k,&m); for(int i=1;i<=n;i++) fa[i]=i; for(int j=1;j<=m;j++) { scanf("%d%d%d%d",&e.u,&e.v,&e.T,&e.t); q1.push(e);q2.push(e); } m=0;int ans=0; while(q2.size()&&m<k) { e=q2.top();q2.pop(); int x=find(e.u),y=find(e.v); if(x==y) continue; ans=max(ans,e.T); m++; fa[x]=y; } while(q1.size()&&m<n-1) { e=q1.top();q1.pop(); int x=find(e.u),y=find(e.v); if(x==y) continue; ans=max(ans,e.t); m++; fa[x]=y; } printf("%d\n",ans); return 0; }
- 1
信息
- ID
- 1870
- 时间
- 1000ms
- 内存
- 125MiB
- 难度
- 5
- 标签
- 递交数
- 0
- 已通过
- 0
- 上传者