码迷,mamicode.com
首页 > 其他好文 > 详细

codeforces 110E Lucky Tree

时间:2018-08-22 00:15:46      阅读:179      评论:0      收藏:0      [点我收藏+]

标签:math   tin   inpu   lld   stream   节点   algorithm   NPU   tor   

传送门: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;

}
View Code

 

codeforces 110E Lucky Tree

标签:math   tin   inpu   lld   stream   节点   algorithm   NPU   tor   

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

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!