第十一章例题 uva 1151 C- Buy or Build

【ORB-SLAM3】使用安卓手机的摄像头运行ORB3 使用安卓手机的摄像头运行ORB-SLAM3单目 阅读详情

自己用dfs实现枚举 + 对刘汝佳大神用二进制枚举的解读 

/*SE:wn------王宁*/
/*Buy or Build 输入输出解读
输入:
城市编号从1-n 
1.告诉你有几个case

2.1 n of cities in the country (1 ≤ n ≤ 1000)  2.2 followed by the number q of existing subnetworks (0 ≤ q ≤ 8).

3.(接下来q行) 
这个网络中的城市数量 + 这个网络买下来的花费 (not greater than 2 × 1e6)+ 网络中城市们的编号

4.(接下来n行)
城市的x y坐标  (ranging from 0 to 3000) c

输出:要有空行 
*/
/*1.运行过程出现的bug原因
当我以为建立网络的花费是距离而不是距离平方的时候
我用%d输出,结果虽然result已经是正确答案(样例中是12.多)
但是这样就输出了负数——检查了一遍才发现
2.重复运行的原因 ! 重复运行是必须的,对于我这种写法来说,
如果一个套餐都没有, v0是不是永远不可能==-1? 
之前的想法(dfs边界判断条件应该是
 if(v0==qn-1),因为是从0开始计数的,而choose在开头
 就已经独立于if-else语句初始化好了)对重复的解读是对的,
 但是没有考虑到特殊情况,结果为了优化又搞出了bug 
 所以还是 if(v0==qn)*/
#include<bits/stdc++.h>
using namespace std; 
struct edge{
  int u,v,d;
  bool operator < (const edge& dhs) const{
    return d < dhs.d;
  }
};
struct point{
  int x,y;
};
const int maxn=1000+5;

vector<edge> database;//经过无套餐参与的最小生成树边集 
vector<edge> total;//经过套餐可能的参与的需要探索的总边集 
vector<edge> tc[10];//每个套餐含有的边集 
vector<edge> v;//经过第一次欧几里得距离的计算处理后得到的原始边集 

vector<point> p;//存储城市的位置的点集 
vector<int> a;//接收套餐中城市编号的数组 
struct edge t;//接受边的临时变量 
struct point pt;//接受城市位置的临时变量 
int first=1;
int fa[maxn];
int nc,qn;//几个城市,几个套餐
int choose[10];//套餐有没有被选择的状态数组
int result=2000000000,ans;//ans是每次枚举套餐得到的局部最小值,result保存全局最小值
int cost[10];//每个套餐花的钱
int find(int x){
  return x==fa[x]?x:fa[x]=find(fa[x]);
}
/*枚举使用了dfs——因为不知道有几个套餐
——知道了用for来写也很丑
——对,我懒得写
——好了,你?怎么还在看
——我不会写行了嘛555……*/
void dfs(int v0, int state){//state表示该套餐有没有被选择,0=没有,1=选择了
  choose[v0]=state;
  if(v0==qn){
    total=database;
    ans=0;
    /*来得到需要处理的边集,注意
    1.vector变量之间可以直接赋值
    2.它的insert用法*/
    for(int i=0;i<qn;i++)
      if(choose[i]==1){ ans=ans+cost[i]; total.insert(total.end(), tc[i].begin(), tc[i].end() ); } 
    //开始在总的边集里面找最小生成树
  sort(total.begin(),total.end());//printf("我到了试验田第一部分啦\n");
  /*for(int i=0;i<total.size();i++){
      cout<<total[i].u<<" "<<total[i].v<<" "<<total[i].d<<endl;
  }*/
  int cnt=0;
  for(int i=1;i<=nc;i++) fa[i]=i;
    for(int i=0;i<total.size();i++){
      int x=find(total[i].u),y=find(total[i].v);
      if(x!=y) {
        fa[x]=y;
        ans=ans+total[i].d;
        if(++cnt==nc-1) break;
      }
    }
   // printf("经过试验,此次的花费ans=%d\n",ans);
    result=min(result,ans);
   // printf("经过试验,此次的result=%d\n",result);
  }
  else{
    dfs(v0+1,0);
    dfs(v0+1,1);
  }
}

int main()
{
  int runs,run,i,j,k,m,c,tmp,cnt;
  cin>>runs;
  for(run=1;run<=runs;run++){
    cin>>nc>>qn;
    /*处理套餐*/
    for(i=0;i<qn;i++)// √ 
    {
      cin>>m>>c; cost[i]=c; a.clear(); tc[i].clear(); 
      for(j=0;j<m;j++) {
        scanf("%d",&tmp);
        a.push_back(tmp);
      }
      for(j=0;j<m;j++) 
      for(k=j+1;k<m;k++){
        t.u=a[j]; t.v=a[k]; t.d=0;
        tc[i].push_back(t);
      }
    }
    /*处理套餐*/

    /*处理城市*/
    v.clear();
    p.clear();
    for(i=1;i<=nc;i++)
    {
      scanf("%d%d",&pt.x,&pt.y);
      p.push_back(pt);
    }
    for(i=0;i<nc;i++)
      for(j=i+1;j<nc;j++)
      {
        t.u=i+1; t.v=j+1; t.d=(p[i].x-p[j].x)*(p[i].x-p[j].x)+(p[i].y-p[j].y)*(p[i].y-p[j].y);
        v.push_back(t);
      }
    sort(v.begin(),v.end());
    /*for(i=0;i<v.size();i++){
      cout<<v[i].u<<" "<<v[i].v<<" "<<v[i].d<<endl;
  } */
    /*处理城市*/

    /*找出最小生成树的n-1条边 √*/
    database.clear(); cnt=0;
    for(i=1;i<=nc;i++) fa[i]=i;
    for(i=0;i<v.size();i++){
      int x=find(v[i].u),y=find(v[i].v);
      if(x!=y) {
        fa[x]=y;
        database.push_back(v[i]);
        if(++cnt==nc-1) break;
      }
    }
    /*total=database;
    for(i=0;i<total.size();i++)
      cout<<total[i].u<<" "<<total[i].v<<" "<<total[i].d<<endl;
    total.insert(total.end(), tc[1].begin(), tc[1].end());
    for(i=0;i<total.size();i++)
      cout<<total[i].u<<" "<<total[i].v<<" "<<total[i].d<<endl;*/
    //for(i=1;i<=nc;i++) cout<<fa[i]<<" "; 
    /*for(i=0;i<database.size();i++)
      cout<<database[i].u<<" "<<database[i].v<<" "<<database[i].d<<endl;*/
    /*找出最小生成树的n-1条边*/

    /*目前状况是:database装载了不考虑套餐时的最小生成树所需要的边
    tc[0~qn-1]装载了每个套餐中含有的边,这些边的权重是0,
    cost记载了每个套餐需要的钱*/
    /*然后呢?我要写一个八层循环?
    如果选择这个套餐,就把这个套餐里面的边包含到总的边集去,然后加上该套餐的花费,
    那么八层的for应该放在什么位置?可是我不知道有几个循环啊
    那就用递归吧?*/
    dfs(0,0);
    dfs(0,1);
    if(first) first=0;
    else cout<<endl;
    printf("%d\n",result);
    result=2000000000;
  }
  return 0;
}

———————帅气不失风度的分割线————————


// UVa1151 Buy or Build
// Rujia Liu processed by SE:wn------王宁
#include<cstdio>
#include<cmath>
#include<cstring>
#include<vector>
#include<algorithm>
using namespace std;

const int maxn = 1000 + 10;
const int maxq = 8;
int n;
int x[maxn], y[maxn], cost[maxq];
vector<int> subn[maxq];

int pa[maxn];
int findset(int x) { return pa[x] != x ? pa[x] = findset(pa[x]) : x; } 

struct Edge {
  int u, v, d;
  Edge(int u, int v, int d):u(u),v(v),d(d) {}
  bool operator < (const Edge& rhs) const {
    return d < rhs.d;
  }
};

// initialize pa and sort e before calling this method
// cnt is the current number of components
int MST(int cnt, const vector<Edge>& e, vector<Edge>& used) {
  if(cnt == 1) return 0;
  int m = e.size();
  int ans = 0;
  used.clear();
  for(int i = 0; i < m; i++) {
    int u = findset(e[i].u), v = findset(e[i].v);
    int d = e[i].d;
    if(u != v) {
      pa[u] = v;
      ans += d;
      used.push_back(e[i]);
      if(--cnt == 1) break;
    }
  }
  return ans;
}

int main() {
  int T, q;
  scanf("%d", &T);
  while(T--) {
    scanf("%d%d", &n, &q);
    for(int i = 0; i < q; i++) {
      int cnt;
      scanf("%d%d", &cnt, &cost[i]);
      subn[i].clear();
      while(cnt--) {
        int u;
        scanf("%d", &u);
        subn[i].push_back(u-1);
      }
    }
    for(int i = 0; i < n; i++) scanf("%d%d", &x[i], &y[i]);

    vector<Edge> e, need;
    for(int i = 0; i < n; i++)
      for(int j = i+1; j < n; j++) {
        int c = (x[i]-x[j])*(x[i]-x[j]) + (y[i]-y[j])*(y[i]-y[j]);
        e.push_back(Edge(i, j, c));
      }

    for(int i = 0; i < n; i++) pa[i] = i;
    sort(e.begin(), e.end());

/*对刘汝佳大神用二进制位运算来实现使用for循环的枚举*/
	int ans = MST(n, e, need);//没有购买套餐的状态
    for(int mask = 0; mask < (1<<q); mask++) {
    /*比如有两个套餐,q=2
    1<<q=4,那么就得到了以下01串:
    000 001 010 011 !100(因为<4)
    对应
    0   1   2   3
    最后两位是不是能刚好满足枚举?*/      
    // union cities in the same sub-network
      for(int i = 0; i < n; i++) pa[i] = i;
      int cnt = n, c = 0;
  		//只要不是0,二进制位与都能和mask
  //然后0,1会在每一轮mask循环里面和mask位与
  //起作用的(购买套餐)是不是有01 10 11?
  //01 和 1<<0=1=01 位与 ,是不是代表着第一个套餐能被选中?
  //同样的,01和1<<1=2=10,额,这个位与就变成0了,
  //(第二个mask)10 和 01,第一个套餐没有选中
  /*10 和 10 选中
  第三个套餐,显然都会选中
  如果q=3,mask 从0000 0001 0010 0011 0100 0101 0110 0111
  等一下,那些有什么特点 1<<i
  1 2 4 
  0001 0010 0100 
  配合所有的状态1<<q,
  0000 0001 0010 0011 0100 0101 0110 0111
  所以,这些状态表明谁可以进来,谁不可以进来
  谁想要进来,必须提供自己本身的身份钥匙,只要
  自己位置上的锁是有洞的(1),就能够通过验证
  */
      for(int i = 0; i < q; i++) if(mask & (1<<i)) {
        c += cost[i];
        /*然后是事先在套餐里面把城市给连接起来*/
        for(int j = 1; j < subn[i].size(); j++) {
          int u = findset(subn[i][j]), v = findset(subn[i][0]);
          if(u != v) { pa[u] = v; cnt--; }
        }
      }
      //dummy有什么用呢 ? 一开始把need放在dummy的位置上能获得没有套餐参与的最小生成树的边,后面就没有用了吧?
	  //嗯,没用了,每次进去都会被清空掉,只有need被保留了下来,话说你使用之前都要重新定义一次,没有clear也一样 
      vector<Edge> dummy;
      ans = min(ans, c + MST(cnt, need, dummy));
    }
    printf("%d\n", ans);
    if(T) printf("\n");
  }
  return 0;
}

 

 

把 MCP Server 直接装进 SAP ABAP:用 Unlimited Display Tools 打通 Agentic SDK 与 SAP ECC / S/4HANA 的最后一公里 摘要:AI与SAP集成的MCP解决方案 企业在AI集成中面临工具链复杂、数据对接繁琐的挑战。Model Context Protocol (MCP)通过标准化工具与数据暴露方式,将集成复杂度从N×M降至N+M。在SAP生态中,MCP Server for SAP直接部署于ABAP层,利用DDIC/CDS视图对接各类Agent SDK,避免中间件风险。 MCP核心包含三类对象: Tools:带元数据的可执行动作 Resources:结构化上下文数据 Prompts:可参数化提示模板 ABAP层实现MCP Se 阅读详情

相关推荐

【AGC】【serverless】【云函数】云函数常见问题

1、云函数添加了AUTH触发器后,在用户执行注册、销户、登录、登出动作时,云函数的event对象会自动触发返回相应信息。比如我在“层”的压缩包里放了config/config.txt,那么我在云函数里怎么调用这个文件?层的目录是:/dcache/layer,函数的目录是/dcache/layer/func。在云函数里往云数据库里插入数据返回的是180000,这是正常吗?已经按照文档在后台对应的云函数里配置了,所需的AUTH触发器。层的用法和放在函数里的用法是相同的。云函数里的层如何调用?

华为开发者联盟 839

8、C++经典例题------小童游玩岛屿顺序

                         8、C++经典例题------小童游玩岛屿顺序 【问题描述】         寒假期间,小童去海边玩,在海边有n个岛屿,工作人员架设了m座桥,每个桥可以连接两个岛屿,如下图所示,小童想要用深度优先搜索的方法游玩一遍所有的岛屿,求小童的游玩顺序。         输入:共m+1行,每行有两个整数,第一行两个整数岛屿数n和桥数m,后面每行的两个数...

chengjunming123的博客 1354

华三模拟器实战:IPSec VPN穿越NAT的完整配置与调试(附常见问题排查)

本文详细解析了华三模拟器中IPSec VPN穿越NAT的完整配置与调试方法,包括基础环境准备、分步配置、ACL协调策略及高级故障排查。通过实战案例和关键参数解析,帮助网络工程师解决IPSec与NAT协同工作的典型问题,提升企业网络安全性。

weixin_33724046的博客 460

修建大桥

小明来到一个由 n 个小岛组成的世界,岛与岛之间通过修建桥,来让岛上的居 民可以去其他的小岛。已知已经修建了 m 座桥,居民们想让小明帮忙计算,最 少还要在修建几座桥,居民们才能去所有的岛。  输入格式: 第一行输入俩个数字 n,m(1≤n≤1000, 0≤m≤n×(n−1)/2), 分别代表岛的个数,和已经修建的桥的个数,岛的编号分别是 1…n。接下来的 m 行,每行俩个数字,代表这俩个编号的...

qq_42887082的博客 601

无人机信号干扰系统设计方案

设计定向阻塞干扰器需要结合射频(RF)技术、功率放大技术和定向天线技术,核心目标是向特定方向发射高功率噪声信号,覆盖目标频段,阻断无人机的通信或导航信号。实际设计中需平衡功率、效率、散热和便携性,同时需考虑抗干扰技术的快速演进(如无人机加密通信和AI避障)。在合法框架下,此类设备可有效应对“黑飞”威胁,但技术滥用风险需严格管控。定向阻塞干扰器的硬件设计核心在于。

wanghao312的博客 3060

实战演练:基于Veristand Custom Device的硬件在环(HIL)数据流控制模块开发

本文详细介绍了基于Veristand Custom Device的硬件在环(HIL)数据流控制模块开发实战。通过LabVIEW环境配置、动态路由逻辑构建、实时处理核心开发及性能优化等关键步骤,帮助工程师快速掌握定制化HIL测试系统的开发技巧,提升测试效率与准确性。

weixin_29206669的博客 475

小童呓语:也说清明

1. 代人扫墓 代人扫墓自古有之,但是以前是看的友情,看的恩情等,但是像这样完全仅仅金钱关系的, 还真前无古人,咱们真是越来越出息了。 寒食莫寒心,清明勿清魂。 2。 宠物墓 人人之间关系太复杂, 还是宠物好,...

clugcpne10995的博客 162

Windows原生环境配置Tensorflow使用GPU

本文讲解如何在Windows原生环境搭建可调用GPU设备进行计算的Tensorflow2.x环境。 区别于WSL,使用Windows原始环境作为开发环境。

天然玩家的博客 1498

栈例题-火车车厢重组

一组火车车厢编号1-n 从右向左经过车站 每节车厢可以临时进站(栈),放过主线上的几节车厢后再重新上路跟上。 输入车厢数和希望得到的车厢顺序,判断是否可能。 CCF教材下册P149,例6.9 代码如下: 1 #include <iostream> 2 #include <string> 3 #include <cmath> ...

336

华为OD机试双机位C卷-热点网站统计 (Py/Java/C/C++/Js/Go)

华为OD机试双机位C卷 热点网站统计,提供C语言、Java、C++、Python、Go、JavaScript源码实现,并提供完整思路讲解。 华为od机考真题 - 热点网站统计。

qq_45776114的博客 779

从Safety Manual到系统安全概念

本文系统阐述了构建功能安全"证据链"的工程化方法论,核心要点包括:1)建立"风险→对策→验证→证据"闭环链条;2)SafetyManual和FMEDA作为关键证据支撑点,前者界定系统安全边界,后者量化诊断覆盖率;3)通过四步法继承芯片安全机制并扩展至系统级;4)形成"设计-分析-验证"三维闭环体系,包括安全目标、技术实现和验证矩阵;5)强调证据链闭环对安全认证和OEM认可的重要性。该方法论实现了从理论要求到工程实践的完整转化,确保安全设计可验证、可

VehSwHwDeveloper的博客 720

UVA1151 Buy Or Build 解题报告

https://vjudge.net/problem/UVA-1151平面上有n个点(1≤n≤1000),你的任务是让所有n个点连通。为此,你可以新建一些边,费用等于两个端点的欧几里德距离。另外还有q(0≤q≤8)个“套餐”可以购买,如果你购买了第i个套餐,该套餐中的所有结点将变得相互连通。第i个套餐的花费为Ci。最容易想到的朴素办法是先枚举购买哪些套餐,把套餐中的边权值都设为0,然后再求最小生成树。枚举量为O(2q),给边排序的时间复杂度为O(n2logn),Kruskal算法过程是O(n2),因此总复杂

qq_45554473的博客 319

LinePhone3.2.7(android端最新版本) sip客户端

SIP客户端For android:LinePhone3.2.7(最新版本),官网地址:http://www.linphone.org/

洛谷 题解 UVA1151 【买还是建 Buy or Build】

【题意】 平面上有\(n(n<=1000)\)个点,你的任务是让所有n个点联通。为此,你可以新建一些边,费用等于两个端点的欧几里得距离平方。另外还有\(q(q<=8)\)个套餐可以购买,如果你购买了第\(i\)个套餐,该套餐中的所有结点将变得相互连接。第\(i\)个套餐的花费为\(C_i\)。 【算法】 \(Kruskal\) 【分析】 最容易想到的算法是:先枚举购买哪些套餐,把套餐中...

weixin_33827590的博客 355

OV9734 DATASHEET,完整规格书

OV9734完整规格书,包括电气参数,尺寸规格,寄存器配置表等

数学建模模型总结

这是本人在两年内准备参加数学建模竞赛搜集到的模型资料,已经经过了本人的筛选和整理,希望能够对准备参加数学建模竞赛的学弟学妹们提供一些帮助!

UVA 1151 Buy or Build (Kruskal+二进制枚举子集)

问题 L: Buy or Build 时间限制: 20 Sec  内存限制: 128 MB 提交: 6  解决: 4 [提交][状态][讨论版] 题目描述 World Wide Networks (WWN) is a leading company that operates large telecommunication networks. WWN would like to

albertluf的博客 263

Statistics and Machine Learning Toolbox

Statistics and Machine Learning Toolbox(带书签),MATLAB统计学习工具

UVA 1151 Buy or Build

#include&lt;bits/stdc++.h&gt; using namespace std; const int M=1e6+5; struct node{ int xx,yy,zz; }f[M],r[M],w[M]; int n,m,l,len; int x[M],y[M],fat[M],num[M],cost[M],a[1010][1010]; int cmp(node q,node...

Napoleon2004的博客 232

【UVA1151】Buy or Build(MST+子集枚举)

今天写多少篇题解呢(⊙o⊙)

AFO 412

Buy or Build 【UVA - 1151】【二进制枚举+Kruskal】

题目链接 很套路的一道题了。 题意:有N个点,P个套餐,选择套餐的话,我们提供Cnt个点,Cost的花费,可以让套餐中的所有的点全部链接上去。其他的点,链接两个点的价值为。 因为P很小,所以直接二进制枚举来做。生成树用Kruskal来,比较的方便。 注意PE。 #include <iostream> #include <cstdio> #incl...

既然弱小,就只顾变强就是了 192

Buy or Build UVA - 1151 买还是建 最小生成树+二进制枚举子集

题目链接 平面上有n个点(1≤n≤1000),你的任务是让所有n个点连通。为此,你可以新建一些边,费用等于两个端点的欧几里德距离。另外还有q(0≤q≤8)个“套餐”可以购买,如果你购买了第i个套餐,该套餐中的所有结点将变得相互连通。第i个套餐的花费为Ci。如图11-6所示,一共有3个套餐: 它的最优解是购买套餐1和套餐2,然后手动连接两条边,如图11-7所示。 【分析】 最容...

Nicolas的博客 585

UVA 1151 Buy or Build (最小生成树)

先求出原图的最小生成树,然后枚举买哪些套餐,把一个套餐内的点相互之间边权为0,直接用并查集缩点。正确性是基于一个贪心, 在做Kruskal算法是,对于没有进入最小生成树的边,排序在它前面的边不会减少。 边比较多,用prim求最小生成树,效果比Kruskal好,枚举套餐的时候在用Kruskal。 prim和dijkstra的区别在于点距离的定义。 #include<bits/std...

weixin_34072857的博客 112

Buy or Build (poj 2784 最小生成树)

题意:n个城市,告诉每个城市的坐标,还有q个联通块,现在要把这n个城市连起来,可以购买联通块(每个有一定的费用),或者新建一条边(费用为点之间的距离的平方),问最小费用是多少。 思路:q很小,二进制枚举选哪些块,每次kruskal一遍,求最小值。

@you! 1717

【poj 2784】Buy or Build (最小生成树)

这是一道最小生成树的题,对理解Kruskal算法很有好处。 数据较小,直接考虑枚举购买“子网络”的情况。 采用Kruskal算法,注意每种情况都要重新初始化并查集。 在购买子网络时就将各个子网络unite()(不同的子网络不需要!)。 复杂度O(2^q * N^2 * lgN)(边有n*(n-1)/2条) (计算发现最大的时间数量级是1e8,用了190ms) #inclu...

weixin_30607029的博客 319

Buy or Build

Description Download as PDF World Wide Networks (WWN) is a leading company that operates large telecommunication networks. WWN would like to setup a new network in Borduria, a nice country that recen

Techay的博客 574

uva1151 Buy or Build

预处理+kruskal

YHaX的博客 575
上一篇: 第十一章例题 B - UVa1395 Slim Span
下一篇: 第十一章例题 UVa753 A Plug for UNIX
JXUFE_ACMer
博客等级 码龄9年 20粉丝 52原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值