首页 > 其他分享 >题解 UVA1537 Picnic Planning

题解 UVA1537 Picnic Planning

时间:2023-09-21 13:12:47浏览次数:49  
标签:node Picnic int 题解 return Planning n1 条边 Hash

这道题在显然是最小生成树,但是很显然我是不会打最小生成树的。


题意描述

给定一张 \(n\) 个点 \(m\) 条边的无向图,求出无向图的一棵最小生成树,满足一号节点的度数不超过给定的整数 \(s\)。

具体思路

首先,看到这种度数最多为 \(s\) 的题,显然想到 wqs 二分。但是 wqs 二分是恰好选 \(s\) 条边是最优,因此考虑证明这一性质。

设平面直角坐标系上的点 \((x,f(x))\),其中 \(x\) 代表选多少条边,\(f(x)\) 代表选 \(x\) 条边时的边权之和。

设当前 \(f(x)\) 最优的情况是选 \(s\) 条边连着 \(1\) 号节点,即此时的生成树边权之和最小。

  • 若我们选多一条边连着 \(1\) 号节点,那么就会多加一条边的权值,显然权值之和没有选 \(s\) 条边优。

  • 若我们选少一条边连着 \(1\) 号节点,那么就会导致有的点要连到其它节点上来保证连通性。由于我们选 \(s\) 条边的时候是最优的,因此我们现在选的点要连到更大的边上,因此权值之和没有选 \(s\) 条边优。

因此 \(f(x)\) 具有凸函数性质,即斜率具有单调性,故可以二分。

image

Code

#include<bits/stdc++.h>
using namespace std;
typedef pair<int,int>PII;
const int N=1100;
unordered_map<string,int>Hash;
int n,m,k,s,fa[N];
struct node{int x,y,c;}a[N];
bool cmp(node n1,node n2){
    if(n1.c+k*(n1.x==1)==n2.c+k*(n2.x==1))return n1.x!=1;
    return n1.c+k*(n1.x==1)<n2.c+k*(n2.x==1);
}
int get(int x){
    if(fa[x]==x)return x;
    return fa[x]=get(fa[x]);
}
PII kruskal(){
    int ans=0,cnt=0;
    for(int i=1;i<=n;i++)fa[i]=i;
    sort(a+1,a+m+1,cmp);
    for(int i=1;i<=m;i++){
        int x=a[i].x,y=a[i].y,c=a[i].c;
        int tx=get(x),ty=get(y);
        if(tx!=ty){
            fa[tx]=ty;
            ans=ans+c;
            if(x==1){
                cnt++;
                ans=ans+k;
            }
        }
    }
    return {cnt,ans};
}
int solve(){
    int l=0,r=1000;
    while(l<=r){
        int mid=(l+r)>>1;k=mid;
        if(kruskal().first>s)l=mid+1;
        else r=mid-1;
    }
    return l;
}
int main(){
	int t;scanf("%d",&t);
	while(t--){
		scanf("%d",&m);
		Hash.clear();n=0;
	    Hash["Park"]=++n;
	    for(int i=1;i<=m;i++){
	        string x,y;int c;
	        cin>>x>>y>>c;
	        if(!Hash[x])Hash[x]=++n;
	        if(!Hash[y])Hash[y]=++n;
	        a[i]=node{Hash[x],Hash[y],c};
	        if(a[i].x>a[i].y)swap(a[i].x,a[i].y);
	    }
	    scanf("%d",&s);
	    printf("Total miles driven: ");
	    k=0;
	    if(kruskal().first>s)k=solve();
	    printf("%d\n",kruskal().second-k*s);
	    if(t)puts("");
	}
    return 0;
}

标签:node,Picnic,int,题解,return,Planning,n1,条边,Hash
From: https://www.cnblogs.com/reclusive2007/p/17719719.html

相关文章

  • 【HarmonyOS】【FAQ】HarmonyOS应用开发相关问题解答(四)
    ​贴接上回。。。 【往期FAQ参考】【HarmonyOS】【FAQ】HarmonyOS应用开发相关问题解答(一)【HarmonyOS】【FAQ】HarmonyOS应用开发相关问题解答(二)【HarmonyOS】【FAQ】HarmonyOS应用开发相关问题解答(三) 【本期FAQ】1、JS服务卡片能实现按钮触摸时更换背景色,离开恢复原来......
  • ABC319题解
    直接从D开始了。D可可爱爱的二分捏。check就按照题目里写的就行了。然后\(l\)的初值要注意一下,就是\(\max^{i\len}_{i=1}a_i\)。代码:#include<bits/stdc++.h>#defineintlonglongusingnamespacestd;constintmaxn=2e5+10;intn,m;inta[maxn];intl,......
  • Friendly Arrays题解
    2023-09-18题目FriendlyArrays难度&重要性(1~10):5题目来源luogu题目算法贪心解题思路一道大水题。这道题解法非常的套路,我们需要对于处理按位或和按位异或时,首先就要把数拆成二进制的形式去考虑。首先我们需要简单了解一下按位或和按位异或的运算规则:按位或,对于两......
  • 使用dom4j解析xml文件及selectNodes取不到值问题解决
    参考文档:https://blog.csdn.net/PARADDD/article/details/131307189https://blog.csdn.net/weixin_37703598/article/details/81273199......
  • asp.net 跨域问题解决
    前言:近期在对接前后端分离的项目中遇到了跨域问题,查了一些资料都比较新,没有比较老的解决方式所以记录一下背景如下:后端最老的aspx前端vue3部署在iis上1.跨域的处理点击查看代码<httpProtocol> <customHeaders> <addname="Access-Control-Allow-Origin"value=......
  • 【POJ 3278】Catch That Cow 题解(广度优先搜索)
    农夫约翰已被告知一头逃亡奶牛的位置,并想立即抓住她。他从一条数字线上的N点(0≤N≤100000)开始,奶牛在同一条数字线上的K点(0≥K≤100000)。农夫约翰有两种交通方式:步行和坐车。*步行:FJ可以在一分钟内从任何点X移动到点X-1或X+1*坐车:FJ可以在一分钟内从任何X点移动到2×X点。如果奶......
  • 题解 [ARC165C] Social Distance on Graph
    赛时:看不懂题,啊这!赛后:就这?题目描述有一个简单相连的无向图,其顶点数为\(n\),编号为\(1\)至\(n\)。图中有\(m\)条加权边,第\(i\)条边连接顶点\(a_i\)和\(b_i\),权重为\(w_i\)。此外,连接两个顶点的简单路径的权重是简单路径中包含的边的权重之和。我们给每个顶点涂上红......
  • QOJ61 Cut Cut Cut! 题解
    题面。题解假设\(1\)号点有\(d\)条出边,给\(d\)条出边赋\(d\)个独立的单位向量,接下来,每个出边记作入边的随机线性组合,那么对于第\(i\)个点,答案就是入边生成的线性空间的秩。正确性证明:对于每个点考虑,假设现在考虑\(i\)号点,将其入边集合记作\(E1_{i}\),出边集合记......
  • 9.20周三(动手动脑问题解决)
    无法编译原因:没有默认构造推出结论:当你给类提供了一个自定义的构造方法,导致系统不在提供默认构造方法了,需要自己提供初始化测试packageorg.example;publicclassInitializeBlockClass{publicintfield=100;{field=200;}publicInitiali......
  • Acwing393. 雇佣收银员 题解 差分约束
    题目链接:https://www.acwing.com/problem/content/description/395/解题思路:差分约束。为了方便起见,定义第\(i\)个时间段为\(i-1:00\)到\(i:00\)这个时间段。首先,为了方便开一个额外的点,令\(R_i\)对应为题目中的\(R(i+1)\),即\(R_i\)表示\(i-1:00\)到\(i:00\)这......