POJ-2421-Constructing Roads 解题报告

来源:互联网 发布:aso优化 app下载 编辑:程序博客网 时间:2024/06/05 22:32

       最小生成树题。好久没写邻接矩阵了。题意:有n个村庄,编号为1~n。你需要建造一些道路使得任意两个村庄是连通的。比如A与B连通当且仅当A与B之间有一条道路或者A与C连通,B与C连通。现在已经建造好了一些道路,你的任务是尽可能使得建造的道路长度短并且让任意两个村庄连通。


       我的解题思路:比较巧的最小生成树题了。没仔细看我还以为是什么双连通分量要缩点什么的算法。其实就是裸求最小生成树,只不过有一些路已经建造好了。


       我的解题代码:Kruskal算法

#include <cstdio>#include <cstdlib>#include <cstring>#include <algorithm>#include <vector>using namespace std;const int N = 111;struct edge{    int x, y;    int len;};int map[N][N];      //图的邻接矩阵edge road[N*N];int rdn;            //未建造的道路数量int father[N];int n, m;void InitRead();void DataProcess();int Find(int x);void Union(int x, int y);int Kruskal();int Mycmp(const void *a, const void *b);int main(){    while (~scanf("%d", &n))    {        InitRead();        DataProcess();    }    return 0;}void InitRead(){    rdn = 0;    for (int i=1; i<=n; ++i)    {        father[i] = i;        for (int j=1; j<=n; ++j)        {            scanf("%d", &map[i][j]);        }    }    scanf("%d", &m);    int a, b;    while (m--)    {        scanf("%d %d", &a, &b);        Union(a, b);    }    return;}void DataProcess(){    for (int i=1; i<=n; ++i)    {        for (int j=1; j<i; ++j)        {            if (Find(i) != Find(j))            {                road[rdn].x = i;                road[rdn].y = j;                road[rdn++].len = map[i][j];            }        }    }    printf("%d\n", Kruskal());    return;}int Find(int x){    int z, y = x;    while (y != father[y])    {        y = father[y];    }    while (x != father[x])    {        z = father[x];        father[x] = y;        x = z;    }    return y;}void Union(int x, int y){    int fx = Find(x);    int fy = Find(y);    father[fx] = fy;    return;}int Kruskal(){    qsort(road, rdn, sizeof(edge), Mycmp);    int ans = 0;    for (int i=0; i<rdn; ++i)    {        if (Find(road[i].x) != Find(road[i].y))        {            Union(road[i].x, road[i].y);            ans += road[i].len;        }    }    return ans;}int Mycmp(const void  *a, const void *b){    return (*(edge *)a).len - (*(edge *)b).len;}


0 0
原创粉丝点击