UVA - 11183 Teen Girl Squad(最小树形图)

来源:互联网 发布:java文件下载原理 编辑:程序博客网 时间:2024/04/28 07:21

题目大意:给出一张有向图,0为根,求出最小树形图

解题思路:模版题

#include <cstdio>#include <cstring>#define N 1010#define M 40010struct Edge{    int u, v, c;}E[M];int n, m;void init (){    scanf("%d%d", &n, &m);    for (int i = 0; i < m; i++)  scanf("%d%d%d", &E[i].u, &E[i].v, &E[i].c);}#define INF 0x3f3f3f3fint vis[N], pre[N], id[N], in[N];int Directed_MST(int root, int n) {    int ans = 0;    int u, v, tmp;    while (1) {        for (int i = 0; i < n; i++)            in[i] = INF;        for (int i = 0; i < m; i++) {            u = E[i].u;            v = E[i].v;            if (u != v && E[i].c < in[v]) {                in[v] = E[i].c;                pre[v] = u;            }        }        for (int i = 0; i < n; i++) {            if (i == root)                continue;            if (in[i] == INF)                return -1;        }        memset(vis, -1, sizeof(vis));        memset(id, -1, sizeof(id));        int subnode = 0;        in[root] = 0;        for (int i = 0; i < n; i++) {            ans += in[i];            tmp = i;            while (vis[tmp] != i && tmp != root && id[tmp] == -1) {                vis[tmp] = i;                tmp = pre[tmp];            }            if (id[tmp] == -1 && tmp != root) {                u = pre[tmp];                while (u != tmp) {                    id[u] = subnode;                    u = pre[u];                }                id[tmp] = subnode++;            }        }        if (subnode == 0)            break;        for (int i = 0; i < n; i++)            if (!(~id[i]))                id[i] = subnode++;        for (int i = 0; i < m; i++) {            tmp = E[i].v;            E[i].u = id[E[i].u];            E[i].v = id[E[i].v];            if (E[i].u != E[i].v)                 E[i].c -= in[tmp];         }        root = id[root];        n = subnode;    }    return ans;}int cas = 1;void solve() {    printf("Case #%d: ", cas++);    int ans = Directed_MST(0,n);        if (ans == -1)            printf("Possums!\n");        else            printf("%d\n", ans);}int main() {    int test;    scanf("%d", &test);    while (test--) {        init();        solve();    }    return 0;}
0 0