HDU 1102 Kruscal算法

题目大意:
给定村庄的数量,和一个矩阵表示每个村庄到对应村庄的距离,矩阵主对角线上均为1

在给定一个数目Q,输入Q行之间已经有通道的a,b

计算还要至少修建多少长度的轨道

这道题目用Kruscal方法进行计算,先将已有路径记为0,再进行所有路径长度的排序(只计算一个下三角或一个上三角,还把主对角线去掉的那种),通过并查集相交的方法,来判断二者是否属于同一个连通分量,由小到大不断找到你选取的路径,将其加起来即可

代码如下:

 1 #include <iostream>
 2 #include<cstdio>
 3 #include<cstring>
 4 #include<algorithm>
 5 using namespace std;
 6 #define N 105
 7
 8 int mat[N][N];
 9 int visit[N],fa[N];
10 struct Path{
11     int x,y,d;
12     bool operator<(const Path &m) const{
13         return d<m.d;
14     }
15 }path[10010];
16
17 int getHead(int x)
18 {
19     int a=x;
20     while(fa[x]!=x) x=fa[x];
21     fa[a]=x;
22     return x;
23 }
24
25 bool Union(int x,int y)
26 {
27     int fa_x=getHead(x);
28     int fa_y=getHead(y);
29     if(fa_x==fa_y) return false;
30     else{
31         fa[fa_x]=fa_y;
32         return true;
33     }
34 }
35 void swap(int &a,int &b)
36 {
37     if(a<b){
38         int temp=a;
39         a=b;
40         b=temp;
41     }
42 }
43
44 int main()
45 {
46     int n,Q,a,b,k,ans;
47     while(scanf("%d",&n)!=EOF){
48         for(int i=1;i<N;i++) fa[i]=i;
49         memset(visit,0,sizeof(visit));
50         k=1,ans=0;
51         for(int i=1;i<=n;i++)
52             for(int j=1;j<=n;j++) cin>>mat[i][j];
53         for(int i=1;i<=n;i++){
54             for(int j=1;j<i;j++) path[k].x=i,path[k].y=j,path[k++].d=mat[i][j];
55         }
56
57         cin>>Q;
58         for(int i=1;i<=Q;i++){
59             cin>>a>>b;
60             swap(a,b);
61             path[(a-1)*(a-2)/2+b].d=0;
62             /*if(!visit[a]) visit[a]=1,count++;
63             if(!visit[b]) visit[b]=1,count++;*/
64         }
65
66         sort(path+1,path+k);
67
68         /*for(int i=1;i<k;i++) cout<<path[i].d<<endl;
69         cout<<"count"<<count<<endl;*/
70         int count=0;
71         for(int i=0;i<k;i++){
72             if(Union(path[i].x,path[i].y)) ans+=path[i].d,count++;
73             if(count==n-1) break;//当然这一步是为了做一个优化,让它可以提前跳出循环,
74                                  //其实不跳出循环让它一直循环结束也是成立的,只是在找到n-1条边之后,
75                                  //Union函数得到的判断均为false因为n个点都进入了同一个集合内
76         }
77         cout<<ans<<endl;
78     }
79     return 0;
80 }

HDU 1102 Kruscal算法

时间: 2024-10-24 19:18:06

HDU 1102 Kruscal算法的相关文章

hdu 1102 prime算法

Constructing Roads Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) Total Submission(s): 15475    Accepted Submission(s): 5907 Problem Description There are N villages, which are numbered from 1 to N, and you should

HDU 1102 Constructing Roads, Prim+优先队列

题目链接:HDU 1102 Constructing Roads Constructing Roads Problem Description There are N villages, which are numbered from 1 to N, and you should build some roads such that every two villages can connect to each other. We say two village A and B are conne

HDU 1102 &amp;&amp; POJ 2421 Constructing Roads (经典MST~Prim)

链接:http://poj.org/problem?id=2421  或   http://acm.hdu.edu.cn/showproblem.php?pid=1102 Problem Description There are N villages, which are numbered from 1 to N, and you should build some roads such that every two villages can connect to each other. We

图论问题(2) : hdu 1102

题目转自hdu 1102,题目传送门 题目大意: 输入一个n*n的邻接矩阵,其中i行j列代表从i到j的路径的长度 然后又m条路已经帮你修好了,求最短要修多长的路才能使所有村庄连接 不难看出,这道题就是标准的最小生成树模板,多水啊 虽然很水,但本人还是调了近1h才把代码调好...... 下面介绍一下解决最小生成树的两个方法: Prim 和 Kruskal 一,Prim(不懂的点这里) Prim的思想和dijkstra的想法很想(如果不知道dijkstra算法的请点这里) 那么Prim的复杂度在为优

hihocoder1098最小生成树(kruscal算法)

kruscal算法描述: kruscal算法的思路是:最初,把所有节点都看成孤立的集合,将图中所有的边按权重从小到大排序,然后依次遍历这些边,若边的两个端点在两个不同的集合中,则合并这条边的端点所属的两个集合,直到选出n-1条边将图中的所有n个节点都合并到了同一个集合,n-1次合并就选出了n-1条边,由这n-1条边和图上的n哥节点所构成的就是我们需要的该图的最小生成树. kruscal算法的性能依赖于边的数目,故对于稀疏图的最小生成树问题,采用kruscal算法比较优越. 我的代码: 1 #in

HDU 1102 最小生成树裸题,kruskal,prim

1.HDU  1102  Constructing Roads    最小生成树 2.总结: 题意:修路,裸题 (1)kruskal //kruskal #include<iostream> #include<cstring> #include<cmath> #include<queue> #include<algorithm> #include<cstdio> #define max(a,b) a>b?a:b using na

hdu 4862 KM算法 最小K路径覆盖的模型

http://acm.hdu.edu.cn/showproblem.php?pid=4862 选t<=k次,t条路要经过所有的点一次并且仅仅一次, 建图是问题: 我自己最初就把n*m 个点分别放入X集合以及Y集合,再求最优匹配,然后连样例都过不了,而且其实当时解释不了什么情况下不能得到结果,因为k此这个条件相当于没用上... 建图方法: 1.X集合和Y集合都放入n*m+k个点,X中前n*m个点和Y中前n*m个点之间,如果格子里的值相等,权就是(收益-耗费),不等就是(-耗费),因为要的是最大收益

hihoCoder#1098 最小生成树二&#183;Kruscal算法

原题地址 以前没写过Kruscal算法,写了才知道原来比Prime算法简单多了... 并查集的应用太经典了! 代码: 1 #include <iostream> 2 #include <cstdlib> 3 4 using namespace std; 5 6 #define MAX_EDGE 1000008 7 #define MAX_POINT 100008 8 9 struct Edge { 10 int a; 11 int b; 12 int len; 13 }; 14 1

HDU 2112 HDU Today (Dijkstra算法)

HDU Today Time Limit: 15000/5000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 13952    Accepted Submission(s): 3264 Problem Description 经过锦囊相助,海东集团终于度过了危机,从此,HDU的发展就一直顺风顺水,到了2050年,集团已经相当规模了,据说进入了钱江肉丝经济开发区500强.这时候