最小生成树

每读入一个城市,把他与之前的所有城市做一次link()

link的内容:

1.如果两个城市直接相连,合并他们的集合(并查集)
2.如果两个城市可以搭桥,添加一条边来连接。如果不可以搭桥,什么也不做。

接着循环所有pa[],如果pa[i]==i,那么这是一个city。这样计算city数量

做kruskal,计算桥的数量和桥的总长度

代码:

#include<iostream>
#include<cstdlib>
#include<algorithm>
#define Size 5005
using namespace std; int n,m;
int city[Size][]; int num=;
int dis=,num_city=,num_bridge=; int pa[Size];
void init(){
for(int i=;i<=n*m;i++){pa[i]=i;}
}
int find(int x){
if(x!=pa[x])pa[x]=find(pa[x]);
return pa[x];
}
bool query(int x,int y){
return find(x)==find(y);
}
void un(int x,int y){
if(query(x,y))return;
pa[find(x)]=find(y);
} struct E{
int a,b,w;
}edge[];
int cnt=;
int add(int a,int b,int w){
cnt++;
edge[cnt].a=a;
edge[cnt].b=b;
edge[cnt].w=w;
} void link(int a,int b){
int cx=abs(city[a][]-city[b][]);
int cy=abs(city[a][]-city[b][]); if(cx<=&&cy<=){un(a,b); return;}
if(cx>=&&cy>=)return; if(cx>=)add(a,b,cx-);
else add(a,b,cy-);
} bool ff(E a,E b){
return a.w<b.w;
} void kruskal(){
sort(edge+,edge++cnt,ff); for(int i=;i<=cnt;i++){
int a=edge[i].a,b=edge[i].b;
if(!query(a,b)){
dis+=edge[i].w;
num_bridge++;
un(a,b);
}
}
} int main(){
cin>>n>>m;
init();
char cc;
for(int i=;i<=n;i++){
for(int j=;j<=m;j++){
cin>>cc;
if(cc=='#'){
num++;
city[num][]=i; city[num][]=j;
for(int k=;k<num;k++){
link(k,num);
}
}
}
}
// cout<<num<<endl;
// for(int i=1;i<=cnt;i++){
// cout<<edge[i].a<<' '<<edge[i].b<<' '<<edge[i].w<<endl;
// }
for(int i=;i<=num;i++){
if(pa[i]==i)num_city++;
}
kruskal();
cout<<num_city<<endl<<num_bridge<<' '<<dis<<endl;
}

code1002 搭桥的更多相关文章

  1. codevs 1002 搭桥

    codevs 第一道题 先贴描述 1002 搭桥  时间限制: 1 s  空间限制: 128000 KB  题目等级 : 黄金 Gold 题解  查看运行结果     题目描述 Description ...

  2. 搭桥|codevs1002|最小生成树|Prim|并查集|Elena

    1002 搭桥  时间限制: 1 s  空间限制: 128000 KB  题目等级 : 黄金 Gold 题目描述 Description 有一矩形区域的城市中建筑了若干建筑物,如果某两个单元格有一个点 ...

  3. 【并查集】【DFS】搭桥

    [codevs1002]搭桥 Description 有一矩形区域的城市中建筑了若干建筑物,如果某两个单元格有一个点相联系,则它们属于同一座建筑物.现在想在这些建筑物之间搭建一些桥梁,其中桥梁只能沿着 ...

  4. codevs1002 搭桥

    题目描述 Description 有一矩形区域的城市中建筑了若干建筑物,如果某两个单元格有一个点相联系,则它们属于同一座建筑物.现在想在这些建筑物之间搭建一些桥梁,其中桥梁只能沿着矩形的方格的边沿搭建 ...

  5. 【wikioi】1002 搭桥(dfs+最小生成树)

    http://wikioi.com/problem/1002/ 今天开始又开始刷水了哈T_T.照着hzwer神犇的刷题记录刷!!! 题解: 一开始我也不会,但是我想到了直接爆搜T_T. 好吧,题解. ...

  6. codevs1002搭桥(建图+Prim)

    /* 先来个灌水法 然后建图跑最小生成树 注意观察题目中的规则 a[1][i]!=a[1][j]&&abs(a[2][i]-a[2][j])<=1 建图的时候可以每一个建筑物都看 ...

  7. codevs1002搭桥(prim)

    题目描述: 这是道题题意有点迷(或者是我语文不好),但其实实际上求的就是图中连通块的个数,然后在连通块与连通块之间连边建图跑最小生成树.但是--这个图可能是不连通的--求桥的数量和总长 于是我立刻想到 ...

  8. 【codevs1002】搭桥(prim)

    题目描述: 这是道题题意有点迷(或者是我语文不好),但其实实际上求的就是图中连通块的个数,然后在连通块与连通块之间连边建图跑最小生成树.但是……这个图可能是不连通的……求桥的数量和总长 于是我立刻想到 ...

  9. 搭桥(codevs 1002)

    题目描述 Description 有一矩形区域的城市中建筑了若干建筑物,如果某两个单元格有一个点相联系,则它们属于同一座建筑物.现在想在这些建筑物之间搭建一些桥梁,其中桥梁只能沿着矩形的方格的边沿搭建 ...

随机推荐

  1. uva216-枚举-简单题

    题意:n个计算机通过电缆连接,怎么连接使用的电缆最少 mmp,死wa不过,memset(vis,0,sizeof(per)),太不小心了 #include <iostream> #incl ...

  2. jqgird

    将jqgird某字段设为超链接,并传递相关参数 cellvalue:为后台传递过来的字段数据 rowObject:为本行数据 实现: formatter:function(cellvalue, opt ...

  3. pythone--002

    元组就是不可修改: 字典的索引不是自增的.  元组和列表是: 默认 是key 通过get  没有这个key  是none get可以有默认值: 通过索引 没有就报错. 检查字典中某个可以是否存在:ha ...

  4. SVN的使用----经历

    一,使用SVN down文件到本机 svn co path1 path2 co是checkout的简写 path1是源文件路径 path2是目标文件存放目录 比如::下面的方式是下载到当前目录. ++ ...

  5. HTML5 Canvas ( 线段端点的样式 ) lineCap

    <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title> ...

  6. JSON.Stringify()和JSON.parse()的比较使用

    1.  JSON.Stringify() 将一个对象解析成字符串 <script> function myonclick() { var value = $('select option: ...

  7. HTML 标签说明

    标签 描述 <!--...--> 定义注释. <!DOCTYPE>  定义文档类型. <a> 定义锚. <abbr> 定义缩写. <acronym ...

  8. 内容方框 fieldset

    Title 登录 用户名 密码 <!DOCTYPE html><html lang="en"><head> <meta charset=& ...

  9. 使用 C++11 编写类似 QT 的信号槽——下篇

    要实现 Signal-Slot,Signal 类中应该拥有一个保存 std::function 的数组: template<class FuncType> class Signal { p ...

  10. windows与linux环境查看jdk安装路径

    windows: set java_home 查看jdk安装路径 java -version 查看jdk版本 linux: whereis java which java(java执行路径) echo ...