codeforces 110E Lucky Tree

传送门:https://codeforces.com/contest/110/problem/E

题意:给你一颗树,节点与节点之间的边有一个边权,定义只由4和7组成的数字是幸运数字,现在要你求一共有多少条路径,使得节点u->v之间至少存在一条边为幸运数字

题解:树形dp+容斥,我们要找有多少条路径上至少存在一条幸运边,那么我们就可以找到所有的不含幸运路径的边然后用所有路径和减去不含幸运路径的边即可

   1,每次输入边权的时候处理边权是否为幸运数字,如果是,那么为1,否则为0

   2,dfs处理,如果边权为0,那么不含幸运数字的路径+1;

   3,容斥,有t条不含幸运数字的边则一共有t*(t-1)*(t-2)种方法,因为是双向边,所以容斥第二次的时候记得*2;

代码如下:

#include <map>
#include <set>
#include <cmath>
#include <ctime>
#include <stack>
#include <queue>
#include <cstdio>
#include <cctype>
#include <bitset>
#include <string>
#include <vector>
#include <cstring>
#include <iostream>
#include <algorithm>
#include <functional>
#define fuck(x) cout<<"["<<x<<"]";
#define FIN freopen("input.txt","r",stdin);
#define FOUT freopen("output.txt","w+",stdout);
//#pragma comment(linker, "/STACK:102400000,102400000")
using namespace std;
typedef long long LL;
typedef pair<int, int> PII;
const int maxn = 1e5+5;
const int INF = 0x3f3f3f3f;
const int MOD = 1e9+7;
struct node{
    int v,next;
    LL w;
}edge[maxn<<2];
int head[maxn],tot;
LL dp[maxn];
void add(int u,int v,int w){
    edge[tot].v=v;
    edge[tot].w=w;
    edge[tot].next=head[u];
    head[u]=tot++;
}
void dfs(int u,int fa){
    dp[u]=0;
    for(int i=head[u];i!=-1;i=edge[i].next){
        int v=edge[i].v;
        if(v==fa) continue;
        dfs(v,u);
        if(edge[i].w==0){
            dp[u]+=dp[v]+1;
            dp[v]=0;
        }
    }
}

int main(){
#ifndef ONLINE_JUDGE
    FIN
#endif
    int u,v;
    LL n,w,f;
    tot=0;
    memset(head,-1,sizeof(head));
    scanf("%lld",&n);
    for(int i=1;i<n;i++){
        scanf("%d%d%lld",&u,&v,&w);
        f=1;
        while(w){
            if(w%10!=4&&w%10!=7) f=0;
            w/=10;
        }
        add(u,v,f);
        add(v,u,f);
    }
    if(n<=2){
        printf("0\n");
        return 0;
    }
    dfs(1,1);
    LL ans=(LL)n*(n-1)*(n-2);
    for(int i=1;i<=n;i++){
        if(dp[i]){
            LL tmp=dp[i]+1;
            ans-=tmp*(tmp-1)*(tmp-2);
            ans-=tmp*(tmp-1)*((LL)n-tmp)*2;
        }
    }
    cout<<ans<<endl;

}

原文地址:https://www.cnblogs.com/buerdepepeqi/p/9515185.html

时间: 2024-07-31 15:08:40

codeforces 110E Lucky Tree的相关文章

Codeforces 109C Lucky Tree 组合计数+dfs

题目链接:点击打开链接 题意: 给定n个点的树,有边权. 定义lucky number:数字只有4或7组成 对于一个三元组(i, j, k) 若path(i,j) 路径上的数字存在lucky number && path(i,k) 路径上的数字存在lucky number 则三元组合法. 问有多少个合法的三元组. ( (i,j,k) != (i,k,j) ) 用全集-补集.dfs出每个只由 非lucky number 构成的联通块 的点数 x . 然后方法数就是 x*(x-1)*(x-2)

CodeForces E. Lucky Array 幸运数列

CodeForces    E. Lucky Array  幸运数列 Petya loves lucky numbers. Everybody knows that lucky numbers are positive integers whose decimal representation contains only the lucky digits 4 and 7. For example, numbers 47, 744, 4 are lucky and 5, 17, 467 are n

Problem - D - Codeforces Fix a Tree

Problem - D - Codeforces  Fix a Tree 看完第一名的代码,顿然醒悟... 我可以把所有单独的点全部当成线,那么只有线和环. 如果全是线的话,直接线的条数-1,便是操作数. 如果有环和线,环被打开的同时,接入到线上.那就是线和环的总数-1. 如果只有环的话,把所有的环打开,互相接入,共需n次操作. #include <cstdio> #include <algorithm> using namespace std; const int maxn =

CodeForces - 383C Propagating tree(dfs + 线段树)

题目大意: 给出一棵树,树上每个节点都有权值,然后有两个操作. 1 x val 在结点x上加上一个值val,x的儿子加上 -val,x的儿子的儿子加上 - (-val),以此类推. 2 x 问x节点的值. 思路分析: 每个节点上加值都是给自己的儿子节点加,而且这个是颗树. 比如样例上的,如果你给node 1加一个值,那么五个节点都加. 再给node 2加个值,2的儿子节点也加了,之前给1加的值也要加到2号节点的儿子. 所以你会发现节点的儿子会存在一个从属的关系. 这样的话,我们可以把所有节点从新

CodeForces 109C 树形DP Lucky Tree

赶脚官方题解写得挺清楚的说,=_= 注意数据范围用long long,否则会溢出. 1 #include <iostream> 2 #include <cstdio> 3 #include <algorithm> 4 #include <cstring> 5 #include <vector> 6 using namespace std; 7 8 const int maxn = 100000 + 10; 9 10 int n; 11 vecto

CodeForces 383C Propagating tree

Propagating tree Time Limit: 2000ms Memory Limit: 262144KB This problem will be judged on CodeForces. Original ID: 383C64-bit integer IO format: %I64d      Java class name: (Any) Iahub likes trees very much. Recently he discovered an interesting tree

Codeforces 121A Lucky Sum

Lucky Sum Time Limit: 2000ms Memory Limit: 262144KB This problem will be judged on CodeForces. Original ID: 121A64-bit integer IO format: %I64d      Java class name: (Any) Petya loves lucky numbers. Everybody knows that lucky numbers are positive int

CF109 C. Lucky Tree 并查集

Petya loves lucky numbers. We all know that lucky numbers are the positive integers whose decimal representations contain only the lucky digits 4 and 7. For example, numbers 47, 744, 4 are lucky and 5, 17, 467 are not. One day Petya encountered a tre

CodeForces 146A Lucky Ticket

Lucky Ticket Time Limit:2000MS     Memory Limit:262144KB     64bit IO Format:%I64d & %I64u Submit Status Practice CodeForces 146A Description Petya loves lucky numbers very much. Everybody knows that lucky numbers are positive integers whose decimal