题意:给出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 + 并查集)的更多相关文章

  1. Minimum Spanning Tree.prim/kruskal(并查集)

    开始了最小生成树,以简单应用为例hoj1323,1232(求连通分支数,直接并查集即可) prim(n*n) 一般用于稠密图,而Kruskal(m*log(m))用于系稀疏图 #include< ...

  2. 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 ...

  3. UVA 11987 - Almost Union-Find(并查集)

    UVA 11987 - Almost Union-Find 题目链接 题意:给定一些集合,操作1是合并集合,操作2是把集合中一个元素移动到还有一个集合,操作3输出集合的个数和总和 思路:并查集,关键在 ...

  4. hdu 1863 畅通工程(Kruskal+并查集)

    畅通工程 Time Limit: 1000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submi ...

  5. POJ 3723 Conscription (Kruskal并查集求最小生成树)

    Conscription Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 14661   Accepted: 5102 Des ...

  6. [CF891C] Envy - Kruskal,并查集

    给出一个 n 个点 m条边的无向图,每条边有边权,共 Q次询问,每次给出 \(k\)条边,问这些边能否同时在一棵最小生成树上. Solution 所有最小生成树中某权值的边的数量是一定的 加完小于某权 ...

  7. UVa 1395 苗条的生成树(Kruskal+并查集)

    https://vjudge.net/problem/UVA-1395 题意: 给出一个n结点的图,求苗条度(最大边减最小边的值)尽量小的生成树. 思路: 主要还是克鲁斯卡尔算法,先仍是按权值排序,对 ...

  8. POJ2032 Building a Space Station(Kruskal)(并查集)

    Building a Space Station Time Limit: 1000MS   Memory Limit: 30000K Total Submissions: 7469   Accepte ...

  9. POJ1251 Jungle Roads(Kruskal)(并查集)

    Jungle Roads Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 23882   Accepted: 11193 De ...

随机推荐

  1. vue项目打包后想发布在apache www/vue 目录下

    使用的是vue-element-admin做示例,可以参考Vue项目根据不同运行环境打包项目,其他项目应该大同小异. 使用vue-router的browserHistory模式,配置mode: 'hi ...

  2. Java基础学习总结(30)——Java 内存溢出问题总结

    Java中OutOfMemoryError(内存溢出)的三种情况及解决办法 相信有一定java开发经验的人或多或少都会遇到OutOfMemoryError的问题,这个问题曾困扰了我很长时间,随着解决各 ...

  3. 洛谷——P1455 搭配购买

    https://www.luogu.org/problem/show?pid=1455 题目描述 明天就是母亲节了,电脑组的小朋友们在忙碌的课业之余挖空心思想着该送什么礼物来表达自己的心意呢?听说在某 ...

  4. 洛谷 P2738 [USACO4.1]篱笆回路Fence Loops

    P2738 [USACO4.1]篱笆回路Fence Loops 题目描述 农夫布朗的牧场上的篱笆已经失去控制了.它们分成了1~200英尺长的线段.只有在线段的端点处才能连接两个线段,有时给定的一个端点 ...

  5. MongoDB查询、索引和聚合

    初始化mongodb数据库 > use deng switched to db deng > db.createCollection("jingdong") #无參数 ...

  6. URL长链接转换为短链接

    URL长链接转换为段链接的工具非常多,可是.小编还是要给大家唠一种方法的: 操作过程例如以下,打开腾讯微博或者其它微,将自己的URL地址值按图片操作:

  7. 编译并使用boost库(win7+boost1.63+vs2015+32位or 64位),超详细,boost于vs2017下编译(64/32bit)

    首先下载得到boost的最新版(目前最新版是1.63) 下载地址: http://www.boost.org   也可以从这里直接下载 http://download.csdn.net/detail/ ...

  8. poj_2777线段树+位运算

    第一次没想到用位运算,不出意料的T了,,, PS:在床上呆了接近两个月后,我胡汉三又杀回来刷题啦-- #include<iostream> #include<cstdio> # ...

  9. 提高FPGA速度的quartus编译选项

    Turning on some optimizations in Quartus II may help increase it. Here are some you may want to try: ...

  10. bzoj1430: 小猴打架(prufer序列)

    1430: 小猴打架 题目:传送门 简要题意: n只互不相识的猴子打架,打架之后就两两之间连边(表示已经相互认识),只有不认识(朋友的朋友都是朋友)的两只猴子才会打架.最后所有的猴子都会连成一棵树,也 ...