标签:
题目大意:给出一张有向图,0为根,求出最小树形图
解题思路:模版题
#include <cstdio>
#include <cstring>
#define N 1010
#define M 40010
struct 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 0x3f3f3f3f
int 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;
}
版权声明:本文为博主原创文章,未经博主允许不得转载。
UVA - 11183 Teen Girl Squad(最小树形图)
标签:
原文地址:http://blog.csdn.net/l123012013048/article/details/47791197