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

UVA 11183 - Teen Girl Squad

题目链接

题意:本质就是给一个有向图,有一些能连接的边,连接有一个代价,问从0能遍历到所有点的,并且代价最小的最小代价

思路:最小树形图的裸题,用朱刘算法求解,验证一下模板

代码:

#include <cstdio>
#include <cstring>

const int MAXNODE = 1005;
const int MAXEDGE = 40005;

typedef int Type;
const Type INF = 0x3f3f3f3f;

struct Edge {
	int u, v;
	Type dist;
	Edge() {}
	Edge(int u, int v, Type dist) {
		this->u = u;
		this->v = v;
		this->dist = dist;
	}
};

struct Directed_MST {
	int n, m;
	Edge edges[MAXEDGE];
	int vis[MAXNODE];
	int pre[MAXNODE];
	int id[MAXNODE];
	Type in[MAXNODE];

	void init(int n) {
		this->n = n;
		m = 0;
	}

	void add_Edge(int u, int v, Type dist) {
		edges[m++] = Edge(u, v, dist);
	}

	void add_Edge(Edge e) {
		edges[m++] = e;
	}

	Type dir_mst(int root) {
		Type ans = 0;
		while (true) {
			for (int i = 0; i < n; i++) in[i] = INF;
			for (int i = 0; i < m; i++) {
				int u = edges[i].u;
				int v = edges[i].v;
				if (edges[i].dist < in[v] && u != v) {
					in[v] = edges[i].dist;
					pre[v] = u;
				}
			}

			for (int i = 0; i < n; i++) {
				if (i == root) continue;
				if (in[i] == INF) return -1;
			}

			int cnt = 0;
			memset(id, -1, sizeof(id));
			memset(vis, -1, sizeof(vis));
			in[root] = 0;
			for (int i = 0; i < n; i++) {
				ans += in[i];
				int 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] = cnt;
					id[v] = cnt++;
				}
			}
			if (cnt == 0) break;
			for (int i = 0; i < n; i++)
				if (id[i] == -1) id[i] = cnt++;
			for (int i = 0; i < m; i++) {
				int v = edges[i].v;
				edges[i].u = id[edges[i].u];
				edges[i].v = id[edges[i].v];
				if (edges[i].u != edges[i].v)
					edges[i].dist -= in[v];
			}
			n = cnt;
			root = id[root];
		}
		return ans;
	}
} gao;

int t, n, m;

int main() {
	int cas = 0;
	scanf("%d", &t);
	while (t--) {
		scanf("%d%d", &n, &m);
		gao.init(n);
		int u, v, d;
		while (m--) {
			scanf("%d%d%d", &u, &v, &d);
			gao.add_Edge(u, v, d);
		}
		int tmp = gao.dir_mst(0);
		printf("Case #%d: ", ++cas);
		if (tmp == -1) printf("Possums!\n");
		else printf("%d\n", tmp);
	}
	return 0;
}
时间: 2024-10-02 15:51:57

UVA 11183 - Teen Girl Squad(最小树形图)的相关文章

POJ 3164Command Network &amp;&amp; UVA 11183 Teen Girl Squad 最小树形图

最小树形图:简单来说,求一个图的G0的最小树形图,先求出最短弧集合E0.若E0不存在,则图G0的最小树形图不存在.若存在且不含有向环,则E0就是T0中的所有的边.如果E0存在且含有有向环,则收缩有向环为一个点u,并形成图G1,继续且G1的最小树形图直至图Gi,若图Gi无最小树形图,则图G0也不存在最小树形图,若Gi有最小树形图Ti.则逐层展开得到T0 具体可以参考这位大牛写的过程:http://www.cnblogs.com/vongang/archive/2012/07/18/2596851.

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

题目大意:给出一张有向图,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("

UVa11183 - Teen Girl Squad(最小树形图-裸)

Problem I Teen Girl Squad Input: Standard Input Output: Standard Output -- 3 spring rolls please. -- MSG'D!! -- Oh! My stomach lining! Strong Bad You are part of a group of n teenage girls armed with cellphones. You have some news you want to tell ev

UVA:11183:Teen Girl Squad (有向图的最小生成树)

Teen Girl Squad Description: You are part of a group of n teenage girls armed with cellphones. You have some news you want to tell everyone in the group. The problem is that no two of you are in the same room, and you must communicate using only cell

kuangbin带你飞 生成树专题 : 次小生成树; 最小树形图;生成树计数

第一个部分 前4题 次小生成树 算法:首先如果生成了最小生成树,那么这些树上的所有的边都进行标记.标记为树边. 接下来进行枚举,枚举任意一条不在MST上的边,如果加入这条边,那么肯定会在这棵树上形成一个环,如果还要维护处树的特点 那么就要在这个环上删去一条边,这样他还是树,删掉的边显然是这条链上权值最大边更可能形成次小生成树.那么就有2中方法可以做. 第一种PRIM在prim时候直接可以做出这个从I到J的链上权值最大的值MAX[i][j]; 同时可以用kruskal同样方式标记树边,然后DFS跑

UVa11183 Teen Girl Squad, 最小树形图,朱刘算法

Teen Girl Squad Input: Standard Input Output: Standard Output You are part of a group of n teenage girls armed with cellphones. You have some news you want to tell everyone in the group. The problem is that no two of you are in the same room, and you

UVA-11183 Teen Girl Squad (最小树形图、朱刘算法模板)

题目大意:给一张无向图,求出最小树形图. 题目分析:套朱-刘算法模板就行了... 代码如下: # include<iostream> # include<cstdio> # include<cstring> # include<algorithm> using namespace std; # define LL long long # define REP(i,s,n) for(int i=s;i<n;++i) # define CL(a,b) me

CF240E Road Repairs(最小树形图-记录路径)

A country named Berland has n cities. They are numbered with integers from 1 to n. City with index 1 is the capital of the country. Some pairs of cities have monodirectional roads built between them. However, not all of them are in good condition. Fo

bzoj4349: 最小树形图

最小树形图模板题…… 这种\(O(nm)\)的东西真的能考到么…… #include <bits/stdc++.h> #define N 60 #define INF 1000000000 using namespace std; int n, m, nn; double ai[N], an[N], ci[2][N][N], ans; int bc[N]; int ini[N], vis[N], inc[N], inl[N]; int dfn; int dfs(int t) { vis[t]