zoukankan      html  css  js  c++  java
  • NOIP 模拟 $19; m w$

    题解 (by;zjvarphi)

    树形 (dp) 题目

    有一个结论:对于一个图,有多少奇度数的点,处以二就是答案,奇度数指的是和它相连的边中被反转的是奇数

    证明很好证

    那么设 (dp_{i,0}) 表示当没翻转 (i->fa_i) 的边时在 (i) 的子树中有多少奇度数点, (dp_{i,1}) 表示翻转了

    那么分情况转移,设 (w1) 表示和 (i) 相连的且在它子树中的边被翻转奇数条时子树中除去 (i) 的答案,此时,若不算和父亲相连的边,这个点就是一个奇度数点

    [dp_{i,0}=w1+1\ dp_{i,1}=w1 ]

    那么 (w2) 就代表偶数

    [dp_{i,0}=w2\ dp_{i,1}=w2+1 ]

    每次需要判断 (i->fa) 的类型,然后必须转移的就不能更新 (dp_{i,0}),不能转移的同理

    Code
    #include<bits/stdc++.h>
    #define ri register signed
    #define p(i) ++i
    using namespace std;
    namespace IO{
        char buf[1<<21],*p1=buf,*p2=buf;
        #define gc() p1==p2&&(p2=(p1=buf)+fread(buf,1,1<<21,stdin),p1==p2)?EOF:*p1++
        template<typename T>inline void read(T &x) {
            ri f=1;x=0;register char ch=gc();
            while(ch<'0'||ch>'9') {if (ch=='-') f=0;ch=gc();}
            while(ch>='0'&&ch<='9') {x=(x<<1)+(x<<3)+(ch^48);ch=gc();}
            x=f?x:-x;
        }
    }
    using IO::read;
    namespace nanfeng{
        #define node(x,y) (node){x,y}
        #define FI FILE *IN
        #define FO FILE *OUT
        template<typename T>inline T cmax(T x,T y) {return x>y?x:y;}
        template<typename T>inline T cmin(T x,T y) {return x>y?y:x;}
        static const int N=1e5+7,INF=1e9+7;
        int first[N],t=1,n;
        struct edge{int v,nxt,w;}e[N<<1];
        inline void add(int u,int v,int w) {e[t].v=v,e[t].w=w,e[t].nxt=first[u],first[u]=t++;}
        struct node{int w1,w2;}dp[N][2];
        inline int operator>(const node &n1,const node &n2) {return n1.w1==n2.w1?n1.w2>n2.w2:n1.w1>n2.w1;}
        inline node operator+(const node &n1,const node &n2) {return node(n1.w1+n2.w1,n1.w2+n2.w2);}
        void dfs(int x,int fa,int w) {
            node tmp1=node(INF,INF);
            node tmp2=node(0,0);
            for (ri i(first[x]),v;i;i=e[i].nxt) {
                if ((v=e[i].v)!=fa) {
                    dfs(v,x,e[i].w);
                    node fg1=cmin(tmp1+dp[v][0],tmp2+dp[v][1]);
                    node fg2=cmin(tmp2+dp[v][0],tmp1+dp[v][1]);
                    tmp1=fg1,tmp2=fg2;
                }
                if (w==1) dp[x][0]=node(INF,INF);
                else dp[x][0]=cmin(node(tmp1.w1+1,tmp1.w2),tmp2);
                if (!w) dp[x][1]=node(INF,INF);
                else dp[x][1]=cmin(node(tmp1.w1,tmp1.w2+1),node(tmp2.w1+1,tmp2.w2+1));
            }
        }
        inline int main() {
            // FI=freopen("nanfeng.in","r",stdin);
            // FO=freopen("nanfeng.out","w",stdout);
            read(n);
            for (ri i(1),u,v,c,w;i<n;p(i)) {
                read(u),read(v),read(c),read(w);
                if (w==2) add(u,v,w),add(v,u,w);
                else add(u,v,c!=w),add(v,u,c!=w);
            }
            dfs(1,0,2);
            printf("%d %d
    ",dp[1][0].w1>>1,dp[1][0].w2);
            return 0;
        }  
    }
    int main() {return nanfeng::main();} 
    
  • 相关阅读:
    Web.xml配置----字符过滤器
    软工第一次作业——自我介绍
    软工第一次作业
    软工实践个人总结
    福州大学结对编程作业(2)
    福州大学结对编程作业(1)
    福州大学软件工程第一次编程作业
    福州大学软件工程第一次个人作业
    软件工程个人总结
    2020软件工程第二次结对作业
  • 原文地址:https://www.cnblogs.com/nanfeng-blog/p/15029133.html
Copyright © 2011-2022 走看看