标签:
时间限制:1秒 内存限制:128兆
In the computer science, a trie is a tree. For a tree, we define the leave node is the node without any descendants and only have an edge connect in. So in this example, the leave node is “to”, “tea”, “ted”, “ten”, “a” and “inn”. And we define the distance between two node is the minimum edge from a node to another node must pass. So the distance between “a” and “te” is 3, “to” and “inn” is 5. Finally, we define the value of a node is the sum of the node to the entire leave node’s distance. And the value of a tree is equal the value of a node which have the minimum value. Now give you a list of words. Put them into a trie, and calculate the value of this trie.2 6 a to tea ted ten inn 4 sa sb sc sd
Case #1: 13 Case #2: 5 ///////////////////////////////////// For the second case, if the root has only one child, it’s a special leaf and must be calculate.
/** 题意:给几个字符串,构成一个字典树,求哪个节点到每个叶子的距离最短的,最短是多少 做法:先建立一个字典树,然后求公共祖先(求得是所有点到叶子节点的最短的距离) **/ #include <iostream> #include <algorithm> #include <cmath> #include <stdio.h> #include <string.h> #include <queue> using namespace std; #define maxn 100010 int tot = 0 ; const int MAXN = 100010; const int DEG = 30; int num[maxn]; int tot2 = 0; int tot3 = 0; int num1[maxn]; int indegree[maxn]; int mmap[maxn]; int mm = 0; struct Node { int x; int y; int flag; Node() {}; Node(int _x, int _y) { x = _x; y = _y; flag = 0; } } node[maxn << 1]; struct Trie { int next[maxn][30], end[maxn]; int root; int L; int newnode() { for(int i = 0; i < 26; i++) { next[L][i] = -1; } end[L++] = 0; return L - 1; } void init() { L = 0; root = newnode(); } void insert(char buf[]) { int len = strlen(buf); int now = root; for(int i = 0; i < len; i++) { if(next[now][buf[i] - ‘a‘] == -1) { next[now][buf[i] - ‘a‘] = newnode(); node[tot].y = next[now][buf[i] - ‘a‘] + 1; node[tot].x = now + 1; node[tot].flag = 0; tot++; } now = next[now][buf[i] - ‘a‘]; } node[tot - 1].flag = 1; num[tot2++] = node[tot - 1].y; end[now]++; } }; Trie ac; struct Edge { int to; int next; } edge[MAXN * 2]; int head[MAXN], tot1; void addedge(int u, int v) { edge[tot1].to = v; edge[tot1].next = head[u]; head[u] = tot1++; } void init() { tot1 = 0; memset(head, -1, sizeof(head)); } int fa[MAXN << 1][DEG]; int deg[MAXN << 1]; void bfs(int root) { queue<int>que; deg[root] = 0; fa[root][0] = root; que.push(root); while(!que.empty()) { int tmp = que.front(); que.pop(); for(int i = 1; i < DEG; i++) { fa[tmp][i] = fa[fa[tmp][i - 1]][i - 1]; } for(int i = head[tmp]; i != -1; i = edge[i].next) { int v = edge[i].to; if(v == fa[tmp][0]) { continue; } deg[v] = deg[tmp] + 1; fa[v][0] = tmp; que.push(v); } } } int LCA(int u, int v) { if(deg[u] > deg[v]) { swap(u, v); } int hu = deg[u], hv = deg[v]; int tu = u, tv = v; for(int det = hv - hu, i = 0; det; det >>= 1, i++) if(det & 1) { tv = fa[tv][i]; } if(tu == tv) { return tu; } for(int i = DEG - 1; i >= 0; i--) { if(fa[tu][i] == fa[tv][i]) { continue; } tu = fa[tu][i]; tv = fa[tv][i]; } return fa[tu][0]; } bool flag[MAXN]; char buf[30]; int main() { //freopen("in.txt", "r", stdin); int Case = 1; int T; scanf("%d", &T); while(T--) { int n; tot = 1; ///边的数目 tot2 = 0; ///叶子节点的数目 如果根节点存在Case 2 中的情况也加进去 tot3 = 0; ///不是叶子的节点的节点 mm = 0; memset(node, 0, sizeof(node)); memset(indegree, 0, sizeof(indegree)); memset(flag, 0, sizeof(flag)); scanf("%d", &n); ac.init(); for(int i = 0; i < n; i++) { scanf("%s", buf); ac.insert(buf); } init(); int yy = 0; for(int i = 1; i < tot; i++) { addedge(node[i].x, node[i].y); addedge(node[i].y, node[i].x); indegree[node[i].x] ++; indegree[node[i].y] ++; yy = max(yy, max(node[i].x, node[i].y)); } for(int i = 1; i < tot; i++) { if(indegree[node[i].x] == 1) { mmap[mm++] = node[i].x; } else { num1[tot3++] = node[i].x; } if(indegree[node[i].y] == 1) { mmap[mm++] = node[i].y; } else { num1[tot3++] = node[i].y; } } sort(mmap, mmap + mm); sort(num1, num1 + tot3); int newmm = unique(mmap, mmap + mm) - mmap; int newtot3 = unique(num1, num1 + tot3) - num1; bfs(1); int mmin = 0xfffffff; for(int i = 1; i <= yy; i++) { int temp = 0; for(int j = 0; j < newmm; j++) { if(i != mmap[j]) { int tt = LCA(i, mmap[j]); int res = 0; res = abs(deg[i] - deg[tt]) + abs(deg[mmap[j]] - deg[tt]); temp += res; } } mmin = min(mmin, temp); } printf("Case #%d: %d\n", Case++, mmin); } return 0; }
标签:
原文地址:http://www.cnblogs.com/chenyang920/p/4786256.html