题意:给出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. npm 6.0.0 版本npminstall报npm:write after end错误

    这两个多月一直开发小程序,今天准备开发公众号,使用Vue-cli 脚手架搭建项目时候, npm install 就报错误,我就奇葩了!心里一万个曹尼玛....... 因为之前使用安装包的提示升级,自己 ...

  2. IIFE 萌新学习笔记

    立即执行函数表达式(IIFE) IIFE:Immediately-Invoked Function Expression(立即执行函数表达式) 一 常用写法: //经常使用的写法(function() ...

  3. luogu P2041 分裂游戏(结论题)

    题意 题解 一开始理解错题意了.以为这题不可解.. 其实这题当n>=3时都是无解的 然后n=1,2时的解都给出来了. 推荐一个博客的证明 #include<iostream> #in ...

  4. maven 安装jar包

    1 下载maven: 下载路径: http://mirrors.hust.edu.cn/apache/maven/maven-3/3.5.0/binaries/apache-maven-3.5.0-b ...

  5. Linux bash常用快捷键

    移动光标 ctrl-a 光标移动到行首 ctrl-e 光标移动到行尾 ctrl+xx 在行首和光标位置直接切换 ctrl-b 光标左移一位 ctrl-f 光标右移一位 alt-b 光标左移一词 alt ...

  6. salt 安装kubernetes集群3节点

    [root@linux-node1 k8s]# tree .├── etcd.sls├── files│   ├── cfssl-1.2│   │   ├── cfssl-certinfo_linux ...

  7. Linux常用软件tree,autojump,lrzsz安装

    tree安装 1.获取压缩文件 wget http://mama.indstate.edu/users/ice/tree/src/tree-1.7.0.tgz 2.解压缩 tar -zxvf tree ...

  8. HTTP——状态码

    (转载) 完整的 HTTP 1.1规范说明书来自于RFC 2616,你可以在http://www.talentdigger.cn/home/link.php?url=d3d3LnJmYy1lZGl0b ...

  9. 【codeforces 370C】Mittens

    [题目链接]:http://codeforces.com/problemset/problem/370/C [题意] 给你n个人,每个人都有一双相同颜色的手套; 然允许在所有人之间交换手套; (每个人 ...

  10. hadoop 2.6.0 LightWeightGSet源码分析

    LightWeightGSet的作用用一个数组来存储元素,而且用链表来解决冲突.不能rehash.所以内部数组永远不用改变大小.此类不支持空元素. 此类也不是线程安全的.有两个类型參数.第一个用于查找 ...