poj2485(Kruskal)

这道题显然是一道最小生成树的问题,参考算法导论中的Kruskal方法,先对路径长度进行排序,然后使用并查集(Disjoint Set Union)来判断节点是否连通,记录连接所有节点的最后一条路径的长度即为最大的长度了。

下面的并查集算法还可以通过设置rank数组记录节点的等级来进一步优化。总的来说还是一道简单题。

#include <cstdio>
#include <algorithm>
using namespace std;

struct Edge{
    int x, y;
    int dis;
};

int pre[501];

int find(int x)
{
    int r = x;
    while (pre[r] != r){
        r = pre[r];
    }
    int i = x, j;
    while (i != r){
        j = pre[i];
        pre[i] = r;
        i = j;
    }
    return r;
}

bool joint(int x, int y)
{
    int xRoot = find(x),
        yRoot = find(y);
    if (xRoot == yRoot)
        return false;
    pre[xRoot] = yRoot;
    return true;
}

bool cmp(Edge e1, Edge e2)
{
    return e1.dis < e2.dis;
}

int main()
{
    int t;
    scanf("%d", &t);
    while (t--){
        int n;
        Edge edge[25001];
        scanf("%d", &n);
        for (int i = 0; i < n; i++){
            pre[i] = i;
        }
        int cnt = 0;
        for (int i = 0; i < n; i++){
            for (int j = 0; j < n; j++){
                int dis;
                scanf("%d", &dis);
                if (i > j)continue;
                edge[cnt].x = i;
                edge[cnt].y = j;
                edge[cnt++].dis = dis;
            }
        }
        sort(edge, edge + cnt, cmp);
        int max = -1;
        for (int i = 0; i < cnt; i++){
            if (joint(edge[i].x, edge[i].y)){
                max = edge[i].dis > max ? edge[i].dis : max;
            }
        }
        printf("%d\n", max);
    }
    return 0;
}
时间: 2024-10-22 08:31:27

poj2485(Kruskal)的相关文章

poj2485 kruskal与prim

Prime: #include<iostream> #include<cstdio> #include<algorithm> using namespace std; #define debug #if defined debug #define CDBG(format,...) printf("File: "__FILE__", Line: %05d: "format"\n", __LINE__, ##__V

poj2485&amp;&amp;poj2395 kruskal

题意:最小生成树的最大边最小,sort从小到大即可 poj2485 #include<stdio.h> #include<string.h> #include<algorithm> using namespace std; #define maxn 505 int map[maxn][maxn],pa[150000],num,n; struct node { int x; int y; int val; }s[150000]; bool cmp(node a,node

POJ-2485 Highways + POJ-1258 Agri-Net 【Kruskal】

整理板子的时候翻出来的题,放在一起写是因为都是Kruskal纯板子题. 1 #include<cstdio> 2 #include<cstring> 3 #include<iostream> 4 #include<algorithm> 5 #include<cmath> 6 #include<string> 7 #include<stack> 8 #include<queue> 9 #include<ve

poj2485

找最小生成树里面最长的边是多少,还是用kruskal做的.. #include<iostream> #include<algorithm> using namespace std; int father[501]; struct n1 { int s,e,w; }; n1 path[30000]; bool cmp(n1 a,n1 b) { return a.w<b.w; } int find(int i) { while(father[i]!=i) { i=father[i

整合:图论存图方法及三种重要做法分析(Kruskal Dijkstra Bellman-Ford)

一.最短生成路的2种存图方法(邻接矩阵和邻接表): 1)邻接矩阵(适合稠密图即边远远多于点): 1.时间复杂度一般在n^2: 2.可以解决重边情况:map[i][j] = min( map[i][j] , input); 3.初始化:a[i][j] = INF;  a[i][i] = 0; 4.邻接矩阵点的最大极限在3000左右 5.图示: 2)邻接表(适合疏密图即边数近似于点数): 1.时间复杂度一般在mlog(n): 2.数组实现邻接表: ①定义:每个节点i都有一个链表,里面保存着从i出发的

POJ-2485 Highways---最小生成树中最大边

题目链接: https://vjudge.net/problem/POJ-2485 题目大意: 求最小生成树中的最大边 思路: 是稠密图,用prim更好,但是规模不大,kruskal也可以过 1 #include<iostream> 2 #include<cstdio> 3 #include<cstring> 4 #include<algorithm> 5 #include<cmath> 6 #include<queue> 7 #in

【BZOJ 3551】[ONTAK2010] Peaks加强版 Kruskal重构树+树上倍增+主席树

这题真刺激...... I.关于Kruskal重构树,我只能开门了,不过补充一下那玩意还是一棵满二叉树.(看一下内容之前请先进门坐一坐) II.原来只是用树上倍增求Lca,但其实树上倍增是一种方法,Lca只是他的一种应用,他可以搞各种树上问题,树上倍增一般都会用到f数组. |||.我们跑出来dfs序就能在他的上面进行主席树了. IV.别忘了离散. V.他可能不连通,我一开始想到了,但是我觉得出题人可能会是好(S)人(B),但是...... #include <cstdio> #include

最小生成树求法 Prim + Kruskal

prim算法的思路 和dijkstra是一样的 每次选取一个最近的点 然后去向新的节点扩张 注意这里的扩张 不再是 以前求最短路时候的到新的节点的最短距离 而是因为要生成一棵树 所以是要连一根最短的连枝 所以关键部分修改一下 dist[u] = min(dist[u], e.cost) --->>e是连接 v 和 u的边 同样地 普同写法O(v^2) 用队列优化后O(E*logV) 1 #include <iostream> 2 #include <stdio.h> 3

HDU 1389 继续畅通工程【最小生成树,Prime算法+Kruskal算法】

继续畅通工程 Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 21871    Accepted Submission(s): 9356 Problem Description 省政府"畅通工程"的目标是使全省任何两个村庄间都可以实现公路交通(但不一定有直接的公路相连,只要能间接通过公路可达即可).现得到城镇道路统计表,表中列