暑假专题4,树形DP补题

A-BZOJ2435

///卡STL,用前向星……

#include<stdio.h>
#include<string.h>
#include<string>
#include<algorithm>
using namespace std;
#define inf 0x3f3f3f3f
#define N 1001005
int ma(int a,int b){return a>b?a:b;}
int mi(int a,int b){return a<b?a:b;}
int abs(int a){ return a>0?a:-a;}
struct edg{
	int v, next,w;
}e[N<<1];
int head[N],n,cnt;
long long ans;
void add(int u,int v,int w){
    e[++cnt].v=v;
    e[cnt].w=w;
    e[cnt].next=head[u];
    head[u]=cnt;
}
int dfs(int x,int pre){
    int t,siz=1;
    for(int i=head[x];i;i=e[i].next){
        int y=e[i].v;
        if(y==pre)  continue;
        t=dfs(y,x);siz+=t;
        ans+=(long long)abs(n-t-t)*e[i].w;
    }
    return siz;
}
int main(){
    scanf("%d",&n);
    int i,x,y,z;
    for(i=1;i<n;i++){
        scanf("%d %d %d",&x,&y,&z);
        add(x,y,z);add(y,x,z);
    }
    dfs(1,0);
    printf("%lld\n",ans);
    return 0;
}

B-HDU6324

将所有结点异或起来,如果==0,则怎么拿双方都是0,平局。若!=0,则对于异或出来的值上的最高位的1,则所有权值中这个位置上的1肯定是个奇数,那只要拿走这个权值,Q就赢了

#include<stdio.h>
int main(){
    int t;
    scanf("%d",&t);
    while(t--){
        int i,n,a,b,ans=0;
        scanf("%d",&n);
        for(int i=1;i<=n;i++){
            scanf("%d",&a);
            ans^=a;
        }
        for(int i=1;i<n;i++)    scanf("%d%d",&a,&b);
        if(ans==0)    printf("D\n");
        else        printf("Q\n");
    }
    return 0;
}

C-BZOJ1060

#include<stdio.h>
#include<string.h>
#include<vector>
#include<map>
#include<string>
#include<algorithm>
using namespace std;
#define inf 0x3f3f3f3f
#define N 500005
struct edg{
    long long int son,w;
};
long long ma(long long a,long long b){return a>b?a:b;}
vector<edg>tree[N];
long long ans,n,son[N];
void dfs(int x,int pre){
    long long maa=-99999999;
    for(int i=0;i<tree[x].size();i++){
        int y=tree[x][i].son;
        if(y!=pre){
            dfs(y,x);
            maa=ma(maa,tree[x][i].w+son[y]);
            //printf("%lld %lld %lld %d\n",maa,tree[x][i].w+son[y],son[y],y);
            if((i==tree[x].size()-1)||(i==tree[x].size()-2&&tree[x][i+1].son==pre)){
                for(int j=0;j<tree[x].size();j++)
                    if(tree[x][j].son!=pre)
                    ans+=(maa-tree[x][j].w-son[tree[x][j].son]);
                     //printf("???%d %d %lld %lld %lld %lld\n",x,j,maa,tree[x][j].w,son[tree[x][j].son],tree[x][j].son);}
                    //printf("%lld>>>\n",ans);}
                son[x]+=maa;
            }
        }
    }
}
int main(){
    while(scanf("%lld",&n)!=EOF){
        int root;
        scanf("%d",&root);
        long long x,y,z;
        for(int i=1;i<n;i++){
            scanf("%lld%lld%lld",&x,&y,&z);
            edg t;
            t.son=x,t.w=z;  tree[y].push_back(t);
            t.son=y;        tree[x].push_back(t);
        }
        ans=0;
        memset(son,0,sizeof(son));
        dfs(root,-1);
        if(n<=2)    printf("0\n");
        else
        printf("%lld\n",ans);
        for(int i=0;i<=n;i++)   tree[i].clear();
    }
    return 0;
}

D BZOJ1369

第一想法是黑白染色染1,2 然后发现不是,如:
9
1 2
1 3
1 4
1 5
5 6
6 7
6 8
6 9

#include<stdio.h>
#include<string.h>
#include<vector>
#include<map>
#include<string>
#include<algorithm>
using namespace std;
#define inf 0x3f3f3f3f
#define N 10005
int ma(int a,int b){return a>b?a:b;}
int mi(int a,int b){return a<b?a:b;}
int n,dp[N][20];
vector<int>tree[N];
void dfs(int x,int pre){
    for(int i=1;i<=14;i++)  dp[x][i]+=i;
    for(int i=0;i<tree[x].size();i++){
        int y=tree[x][i];
        if(y==pre)      continue;
        dfs(y,x);
        for(int j=1;j<=14;j++){
            int mm=inf;
            for(int k=1;k<=14;k++)
                if(k!=j)    mm=mi(mm,dp[y][k]);
            dp[x][j]+=mm;
        }
    }
}
int main(){
    scanf("%d",&n);
    int x,y;
    for(int i=1;i<n;i++){
        scanf("%d%d",&x,&y);
        tree[x].push_back(y);
        tree[y].push_back(x);
    }
    dfs(1,-1);
    int ans=inf;
    for(int i=1;i<=14;i++)      ans=mi(ans,dp[1][i]);
    printf("%d\n",ans);
    return 0;
}

E BZOJ1864

c

F BZOJ3573

在这里插入代码片
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值