您的位置:首页 > 其它

hdoj1879 继续畅通工程(Prime || Kruskal)

2017-12-03 21:08 253 查看

题目链接

http://acm.hdu.edu.cn/showproblem.php?pid=1879

思路

这题和hdoj1102很像,图中的有一些路已经修好了,对于这些已经修好的路,我们令还需要修的长度为0即可,然后进行Prime算法或者Kruskal算法。

代码

Prime算法:

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

const int INF = 0x7fffffff;
const int N = 100 + 10;
int map

;
int dist
;
int n;

void prime()
{
int min_edge, min_node;
for (int i = 1; i <= n; i++)
dist[i] = INF;
int ans = 0;
int now = 1;
for (int i = 1; i < n; i++)
{
dist[now] = -1;
min_edge = INF;
for (int j = 1; j <= n; j++)
{
if (j != now&& dist[j] >= 0)
{
if (map[now][j] >= 0)    //注意是map[now][j]>=0,因为有些路已经修好了,初始化时令其长度为0
dist[j] = min(dist[j], map[now][j]);
if (dist[j] < min_edge)
{
min_edge = dist[j];    // //min_edge存储与当前结点相连的最短的边
min_node = j;
}
}
}
ans += min_edge;    // //ans存储最小生成树的长度
now = min_node;
}
printf("%d\n", ans);
}

int main()
{
//freopen("hdoj1879.txt", "r", stdin);
while (scanf("%d", &n) == 1 && n)
{
memset(map, 0, sizeof(map));
int a, b, d, s;
for (int i = 0; i < n*(n - 1) / 2; i++)
{
scanf("%d%d%d%d", &a, &b, &d, &s);
if (s == 0)
map[a][b] = map[b][a] = d;
else if (s == 1) map[a][b] = map[b][a] = 0;
}
prime();
}
return 0;
}

Kruskal算法:

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

struct Edge
{
int a, b, dist;

Edge() {}
Edge(int a, int b, int d) :a(a), b(b), dist(d) {}
bool operator < (Edge edge)
{
return dist < edge.dist;
}
};

const int N = 100 + 10;
vector<Edge> v;
int p
;
int n;

int find_root(int x)
{
if (p[x] == -1)
return x;
else return find_root(p[x]);
}

void kruskal()
{
memset(p, -1, sizeof(p));
sort(v.begin(), v.end());     //将边按边长从短到长排序
int ans = 0;
for (int i = 0; i < v.size(); i++)
{
int ra = find_root(v[i].a);
int rb = find_root(v[i].b);
if (ra != rb)
{
ans += v[i].dist;
p[ra] = rb;
}
}
printf("%d\n", ans);
}

int main()
{
//freopen("hdoj1879.txt", "r", stdin);
while (scanf("%d", &n) == 1 && n)
{
v.clear();
int m = n*(n - 1) / 2;
int a, b, d, s;
for (int i = 0; i < m; i++)
{
scanf("%d%d%d%d", &a, &b, &d, &s);
if (s == 0)
v.push_back(Edge(a, b, d));
else if (s == 1) v.push_back(Edge(a, b, 0));
}
kruskal();
}
return 0;
}

 

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: