Connect the Campus (Uva 10397 Prim || Kruskal + 并查集)
题意:给出n个点的坐标,要把n个点连通,使得总距离最小,可是有m对点已经连接,输入m,和m组a和b,表示a和b两点已经连接。
思路:两种做法。(1)用prim算法时,输入a,b。令mp[a][b]=0。然后进行一遍prim(2)Kruskal算法+并查集
代码:
//prim写法
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>
#include <string>
#include <map>
#include <stack>
#include <vector>
#include <set>
#include <queue>
#pragma comment (linker,"/STACK:102400000,102400000")
#define pi acos(-1.0)
#define eps 1e-6
#define lson rt<<1,l,mid
#define rson rt<<1|1,mid+1,r
#define FRE(i,a,b) for(i = a; i <= b; i++)
#define FREE(i,a,b) for(i = a; i >= b; i--)
#define FRL(i,a,b) for(i = a; i < b; i++)
#define FRLL(i,a,b) for(i = a; i > b; i--)
#define mem(t, v) memset ((t) , v, sizeof(t))
#define sf(n) scanf("%d", &n)
#define sff(a,b) scanf("%d %d", &a, &b)
#define sfff(a,b,c) scanf("%d %d %d", &a, &b, &c)
#define pf printf
#define DBG pf("Hi\n")
typedef long long ll;
using namespace std; #define INF 0x3f3f3f3f
#define mod 1000000009
const int maxn = 1005;
const int MAXN = 2005;
const int MAXM = 200010;
const int N = 1005; struct Node
{
double x,y;
}node[maxn]; int n,m;
double mp[maxn][maxn];
double dist[maxn];
bool vis[maxn]; double Dis(Node n1,Node n2)
{
return sqrt((n1.x-n2.x)*(n1.x-n2.x)+(n1.y-n2.y)*(n1.y-n2.y));
} double prim()
{
int i,j,now;
double mi;
mem(vis,false);
mem(dist,INF);
for (i=1;i<=n;i++)
dist[i]=mp[1][i];
dist[1]=0;
vis[1]=true;
for (i=1;i<=n;i++)
{
now=-1;
mi=INF;
for (j=1;j<=n;j++)
{
if (!vis[j]&&mi>dist[j])
{
now=j;
mi=dist[j];
}
}
if (now==-1) break;
vis[now]=true;
for (j=1;j<=n;j++)
{
if (!vis[j]&&dist[j]>mp[now][j])
dist[j]=mp[now][j];
}
}
double ans=0;
for (i=1;i<=n;i++)
ans+=dist[i];
return ans;
} int main()
{
#ifndef ONLINE_JUDGE
freopen("C:/Users/lyf/Desktop/IN.txt","r",stdin);
#endif
int i,j,u,v;
while (~sf(n))
{
for (i=1;i<=n;i++)
scanf("%lf%lf",&node[i].x,&node[i].y);
for (i=1;i<=n;i++)
{
for (j=1;j<=n;j++)
if (i==j) mp[i][j]=0;
else mp[i][j]=Dis(node[i],node[j]);
}
sf(m);
for (i=0;i<m;i++) //在同一个联通块的距离直接赋为0
{
sff(u,v);
mp[u][v]=mp[v][u]=0;
}
printf("%.2f\n",prim());
}
return 0;
} //Kruskal+并查集写法
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>
#include <string>
#include <map>
#include <stack>
#include <vector>
#include <set>
#include <queue>
#pragma comment (linker,"/STACK:102400000,102400000")
#define pi acos(-1.0)
#define eps 1e-6
#define lson rt<<1,l,mid
#define rson rt<<1|1,mid+1,r
#define FRE(i,a,b) for(i = a; i <= b; i++)
#define FREE(i,a,b) for(i = a; i >= b; i--)
#define FRL(i,a,b) for(i = a; i < b; i++)
#define FRLL(i,a,b) for(i = a; i > b; i--)
#define mem(t, v) memset ((t) , v, sizeof(t))
#define sf(n) scanf("%d", &n)
#define sff(a,b) scanf("%d %d", &a, &b)
#define sfff(a,b,c) scanf("%d %d %d", &a, &b, &c)
#define pf printf
#define DBG pf("Hi\n")
typedef long long ll;
using namespace std; #define INF 0x3f3f3f3f
#define mod 1000000009
const int maxn = 1005;
const int MAXN = 1000000;
const int MAXM = 200010;
const int N = 1005; struct Node
{
double x,y;
}node[maxn]; struct Edge
{
int u,v;
double len;
}edge[MAXN]; int n,m,cnt;
int father[maxn]; int cmp(Edge e1,Edge e2)
{
return e1.len<e2.len;
} void init()
{
cnt=0;
for (int i=0;i<=n;i++)
father[i]=i;
} double Dis(Node n1,Node n2)
{
return sqrt((n1.x-n2.x)*(n1.x-n2.x)+(n1.y-n2.y)*(n1.y-n2.y));
} int find_father(int x)
{
if (x!=father[x])
father[x]=find_father(father[x]);
return father[x];
} double Kruskal()
{
int i,j;
double ans=0;
sort(edge,edge+cnt,cmp);
for (i=0;i<cnt;i++)
{
int fu=find_father(edge[i].u);
int fv=find_father(edge[i].v);
if (fu!=fv)
{
ans+=edge[i].len;
father[fu]=fv;
}
}
return ans;
} int main()
{
#ifndef ONLINE_JUDGE
freopen("C:/Users/lyf/Desktop/IN.txt","r",stdin);
#endif
int i,j,u,v;
while (~sf(n))
{
init();
for (i=1;i<=n;i++)
scanf("%lf%lf",&node[i].x,&node[i].y);
for (i=1;i<n;i++)
{
for (j=i+1;j<=n;j++)
{
if (i==j) continue;
else
{
double x=Dis(node[i],node[j]);
edge[cnt].u=i;
edge[cnt].v=j;
edge[cnt++].len=x;
}
}
}
sf(m);
for (i=1;i<=m;i++)
{
sff(u,v);
int fu=find_father(u);
int fv=find_father(v);
if (fu!=fv)
father[fu]=fv;
}
printf("%.2f\n",Kruskal());
}
return 0;
}
Connect the Campus (Uva 10397 Prim || Kruskal + 并查集)的更多相关文章
- Minimum Spanning Tree.prim/kruskal(并查集)
开始了最小生成树,以简单应用为例hoj1323,1232(求连通分支数,直接并查集即可) prim(n*n) 一般用于稠密图,而Kruskal(m*log(m))用于系稀疏图 #include< ...
- TOJ 2815 Connect them (kruskal+并查集)
描述 You have n computers numbered from 1 to n and you want to connect them to make a small local area ...
- UVA 11987 - Almost Union-Find(并查集)
UVA 11987 - Almost Union-Find 题目链接 题意:给定一些集合,操作1是合并集合,操作2是把集合中一个元素移动到还有一个集合,操作3输出集合的个数和总和 思路:并查集,关键在 ...
- hdu 1863 畅通工程(Kruskal+并查集)
畅通工程 Time Limit: 1000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) Total Submi ...
- POJ 3723 Conscription (Kruskal并查集求最小生成树)
Conscription Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 14661 Accepted: 5102 Des ...
- [CF891C] Envy - Kruskal,并查集
给出一个 n 个点 m条边的无向图,每条边有边权,共 Q次询问,每次给出 \(k\)条边,问这些边能否同时在一棵最小生成树上. Solution 所有最小生成树中某权值的边的数量是一定的 加完小于某权 ...
- UVa 1395 苗条的生成树(Kruskal+并查集)
https://vjudge.net/problem/UVA-1395 题意: 给出一个n结点的图,求苗条度(最大边减最小边的值)尽量小的生成树. 思路: 主要还是克鲁斯卡尔算法,先仍是按权值排序,对 ...
- POJ2032 Building a Space Station(Kruskal)(并查集)
Building a Space Station Time Limit: 1000MS Memory Limit: 30000K Total Submissions: 7469 Accepte ...
- POJ1251 Jungle Roads(Kruskal)(并查集)
Jungle Roads Time Limit: 1000MS Memory Limit: 10000K Total Submissions: 23882 Accepted: 11193 De ...
随机推荐
- BZOJ 2555: SubString 后缀自动机_LCT
很水的一道题,就是有些细节没注意到. 比如说将调试信息误以为是最终结果而多调了20分钟QAQ ..... 我们注意到,每新加一个节点,改变的是该节点沿着 Parent 走一直走到根节点. 对应的,在 ...
- 路飞学城Python-Day17
[1.编程范式] 1.面向过程编程 2.面向对象编程 [2.面向过程编程] 面向过程:核心就是过程 什么是过程? 过程指的是解决问题的步骤,先做什么,在作什么,面向过程就像是设计一个流水线,是一种 ...
- WebSocket 前端封装
$.extend({ socketWeb:function (opt) { if("WebSocket" in window){ var setting=$.extend({ ur ...
- luogu P4062 [Code+#1]Yazid 的新生舞会(线段树+套路)
今天原来是平安夜啊 感觉这题是道好题. 一个套路枚举权值\(x\),把权值等于\(x\)的设为1,不等于的设为-1,然后问题转化为多少个区间权值和大于. 发现并不是很好做,还有一个套路,用前缀和查分来 ...
- argparse模块入门介绍——基于python3.7
转载:https://blog.csdn.net/weixin_41796207/article/details/80846406 首先说明,本人是想要学习如何使用argparse模块,打造命令行程序 ...
- docker mysql 文件挂载和MySQL字符集设置
原文:docker mysql 文件挂载和MySQL字符集设置 docker run -p 3306:3306 --name mysql -v /usr/local/mysql/my.cnf:/etc ...
- xml布局内容总结(四)--Android
(1)对于xml编写界面较复杂的情况下,使用include会使得编写和查看更清楚 <LinearLayout android:layout_width="mat ...
- Node.js 博客实例(十)pv统计和留言统计
原教程 https://github.com/nswbmw/N-blog/wiki/_pages的第十章,因为版本号等的原因,在原教程基础上稍加修改就可以实现. post.js中将var post={ ...
- OpenCASCADE直线与平面求交
OpenCASCADE直线与平面求交 在<解析几何>相关的书中都给出了直线和平面的一般方程和参数方程.其中直线的一般方程有点向式形式的. 由于过空间一点可作且只能作一条直线平行于已知直线, ...
- hdoj--1005--Number Sequence(规律题)
Number Sequence Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others) ...