今晚的比赛(2011.12.4)

  昨晚做cf刚被虐完,还被虐感冒了。然后今晚又有一个内部测试赛。头疼+困+不想做 = 这次的比赛。最后过了一道题,用很暴力很暴力的方法过的。估计的焘哥出题时加的数据不强。

这次被虐是必然的。。。我现在就有一个念头,那就是睡觉。。。。TT

贴一下D题的代码吧,偶唯一的一个题。。。。

题目描述

Tom喜欢幸运数。我们都知道一个正整数是幸运数当且仅当其十进制表示形式只包含数字4和7.例如,数47,744,4是幸运的,而5,17,467不是。

    一天Tom邂逅了一棵有n个结点的树。另外,他发现,这棵树的是带权的,也即树的每条边都有一个权值(一个正整数)。只有当一条边的权值是幸运数时我们才说这条边是幸运的。大家可以注意到,一棵树是一个具有n个结点恰好有n-1条边的无向连通图。

      Tom想知道到存在多少顶点三元组(i,j,k),满足从i到j的路径上必须存在至少一条幸运边,同时满足从i到k的路径上必须存在至少一条幸运边(三个顶点两两不相同)。三元组中的三个数顺序是有关的,顺序不同整体也是不同的,例如,三元组(1,2,3)不等于三元组(2,1,3),也不等于三元组(1,3,2)。

   找出存在多少这样的顶点三元组。

输入

输入数据由多组,处理到文件结束。每组第一行是一个正整数n(1<=n<=50)——顶点的个数。接下来n-1行,每行三个数:Ui,Vi,Wi(1 < = Ui,Vi < = n, 1 < = Wi < = 10^9)——被一条边连接的两个顶点以及这条边的权值。

输出

    每组一行,仅有一个数,即要求的三元组的总个数。

示例输入

4 1 2 4 3 1 2 1 4 7 4 1 2 4 1 3 47 1 4 7447

示例输出

16 24
 
My Code:
View Code
#include <iostream>
#include <cstdio>
#include <cstring>

using namespace std;

const int N = 55;
const int M = 10000;

const int inf = ~ 0u >> 2;

int pre[N];
int g[N][N];
bool flag[N][N];
bool vis[N];
int n, ans;

bool is_luck(int x) {
int t;
while(x) {
t = x%10;
if(t != 4 && t != 7) return false;
x /= 10;
}
return true;
}

bool is_luck_tree(int s, int e) {
int q[N];
int f, r, v, i;
f = r = 0; q[0] = s;
memset(vis, 0, sizeof(vis));
vis[s] = true;
memset(pre, 0, sizeof(pre));
pre[s] = 0;
while(f <= r) {
v = q[f++];
if(v == e) break;
for(i = 1; i <= n; i++) {
if(g[v][i] > 0 && !vis[i]) {
pre[i] = v;
q[++r] = i;
vis[i] = true;
}
}
}
int t, x;
x = e;
t = pre[e];
//printf("%d ", e);
while(t != 0) {
//printf("%d ", t);
if(flag[t][x]) return true;
x = t;
t = pre[t];

}
return false;
}

int main() {
//freopen("data.in", "r", stdin);

int i, j, u, v, w, k;
while(~scanf("%d", &n)) {
memset(flag, 0, sizeof(flag));
memset(g, 0, sizeof(g));

for(i = 0; i < n-1; i++) {
scanf("%d%d%d", &u, &v, &w);
if(is_luck(w)) flag[u][v] = flag[v][u] = true;
g[u][v] = g[v][u] = w;
}
ans = 0;
for(i = 1; i <= n; i++) {
for(j = 1; j <= n; j++) {
if(i == j) continue;
if(is_luck_tree(i, j)) {
for(k = 1; k <= n; k++) {
if(k == i || k == j) continue;
if(is_luck_tree(i, k)) {
ans++;
//printf("%d %d %d\n", i, j, k);
}
}
}
}
}
//if(is_luck_tree(2, 3)) cout << "OK" << endl;
cout << ans << endl;
}
return 0;
}
posted @ 2011-12-04 21:27  AC_Von  阅读(272)  评论(2编辑  收藏  举报