POJ 3164 最小树形图

来源:互联网 发布:末知死亡阿辛为图片 编辑:程序博客网 时间:2024/05/04 00:01
#include <cstdio>#include <cstring>#include <algorithm>#include <cmath>using namespace std;const int maxn = 1E2 + 10;const int INF = 1 << 30;struct Edge{int u, v;double w;};Edge edge[maxn * maxn];struct Node{double x, y;};Node node[maxn];double Get_Dist(int a, int b){double d1 = (node[a].x - node[b].x) * (node[a].x - node[b].x);double d2 = (node[a].y - node[b].y) * (node[a].y - node[b].y);return sqrt(d1 + d2);}int n, m, pre[maxn], vis[maxn], id[maxn];double in[maxn];double DMST(int root, int n, int m){double res = 0;int  u, v;while (true){//memset(in, INF, sizeof(in));for (int i = 0; i < n; i++) in[i] = INF;memset(id, -1, sizeof(id));memset(vis, -1, sizeof(vis));for (int i = 0; i < m; i++)if (edge[i].u != edge[i].v && edge[i].w < in[edge[i].v]){pre[edge[i].v] = edge[i].u;in[edge[i].v] = edge[i].w;}for (int i = 0; i < n; i++)if (i != root && in[i] == INF)return -1;int tn = 0;in[root] = 0;for (int i = 0; i < n; i++){res += in[i];v = i;while (vis[v] != i && id[v] == -1 && v != root)vis[v] = i, v = pre[v];if (v != root && id[v] == -1){for (int u = pre[v]; u != v; u = pre[u]) id[u] = tn;id[v] = tn++;}}if (tn == 0) break;for (int i = 0; i < n; i++) if (id[i] == -1) id[i] = tn++;for (int i = 0; i < m;){v = edge[i].v;edge[i].u = id[edge[i].u];edge[i].v = id[edge[i].v];if (edge[i].u != edge[i].v) edge[i++].w -= in[v];else swap(edge[i], edge[--m]);}n = tn;root = id[root];}return res;}int main(int argc, char const *argv[]){while (~scanf("%d%d", &n, &m)){for (int i = 0; i < n; i++) scanf("%lf%lf", &node[i].x, &node[i].y);for (int i = 0; i < m; i++){scanf("%d%d", &edge[i].u, &edge[i].v);edge[i].u--, edge[i].v--;edge[i].w = edge[i].u == edge[i].v ? INF : Get_Dist(edge[i].u, edge[i].v);}double ans = DMST(0, n, m);if (ans == -1) printf("poor snoopy\n");else printf("%.2lf\n", ans);}return 0;}


最小树形图的模板题。

0 0
原创粉丝点击