zoukankan      html  css  js  c++  java
  • NOIP 模拟 $13; ext{卡常题}$

    题解

    一道环套树的最小点覆盖题目,所谓环套树就是有在 (n) 个点 (n) 条边的无向联通图中存在一个环

    我们可以发现其去掉一条环上的边后就是一棵树

    那么对于此题,我们把所有 (x) 方点当点 (y) 方点当边,随便找一条环上的边删掉,然后分别从此边的两个端点做树形 (dp)

    对于一条边上的两个点,我们一定要选一个,但不需要都选,类似例题

    所以方程很好推,(dp_{i,0}) 表示不选 (i) 后覆盖 (i) 子树的最小费用,(dp_{i,0}) 表示选 (i) 后覆盖 (i) 子树的最小费用

    [dp_{x,0}=sum_v^{vin son_x}dp_{v,1} ]

    [dp_{x,1}=sum_v^{vin son_x}min(dp_{v,0},dp_{v,1}) ]

    最后取两个端点中值最小的,因为我们也要覆盖被断开的边,所以端点必须要选取一个

    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 cmax(x,y) ((x)>(y)?(x):(y))
        #define cmin(x,y) ((x)>(y)?(y):(x))
        #define FI FILE *IN
        #define FO FILE *OUT
        static const int N=1e6+7;
        int dp[N][2],first[N],cst[N],vis[N],bk1,bk2,t=1,n,a,b;
        struct edge{int v,nxt;}e[N<<1];
        inline void add(int u,int v) {
            e[t].v=v,e[t].nxt=first[u],first[u]=t++;
            e[t].v=u,e[t].nxt=first[v],first[v]=t++;
        }
        void dfs_pre(int x,int fa) {
            if (vis[x]) {bk1=x,bk2=fa;return;}
            vis[x]=1;
            for (ri i(first[x]),v;i;i=e[i].nxt) {
                if ((v=e[i].v)==fa) continue;
                dfs_pre(v,x);
            }
        }
        void dfs(int x,int fa) {
            dp[x][0]=0,dp[x][1]=cst[x];
            for (ri i(first[x]),v;i;i=e[i].nxt) {
                if ((v=e[i].v)==fa||x==bk1&&v==bk2||x==bk2&&v==bk1) continue;
                dfs(v,x);
                dp[x][0]+=dp[v][1];
                dp[x][1]+=cmin(dp[v][1],dp[v][0]);
            }
        }
        inline int main() {
            // FI=freopen("nanfeng.in","r",stdin);
            // FO=freopen("nanfeng.out","w",stdout);
            read(n),read(a),read(b);
            for (ri i(1),v1,v2;i<=n;p(i)) {
                read(v1),read(v2);
                cst[v1]+=a,cst[v2]+=b;
                add(v1,v2);
            }
            dfs_pre(1,0),dfs(bk1,0);
            ri tmp=dp[bk1][1];
            dfs(bk2,0);
            tmp=cmin(tmp,dp[bk2][1]);
            printf("%d
    ",tmp);
            return 0;
        } 
    }
    int main() {return nanfeng::main();}
    
  • 相关阅读:
    模仿outlook快捷方式栏的一个控件
    买了一本书《Programming pearls》编程珠玑(88上的数学题目(1))
    一个IE动画图标的小例子
    对水波特效实现原理的解释
    向量空间的几何变换
    一个简单Led控件
    【转载】配置(visual studio.net已检测到指定的web服务器运行的不是asp.net1.1版)
    最近学习ASP2.0相关的几个小问题(非创新性文章)
    一道c的面试题,大数相乘。
    Led控件(2)——Led显示屏模拟
  • 原文地址:https://www.cnblogs.com/nanfeng-blog/p/15006464.html
Copyright © 2011-2022 走看看