HDU 5770 Treasure

给定一棵树,树上有m个宝箱,每个宝箱都有一个把钥匙,以及各自的价值,要先拿到钥匙才可以开宝箱,必须开掉所有能开的宝箱。要求选择一条简单路径,使得最后获得的总价值最大。

官方题解:

假设钥匙在节点A,宝箱在节点BC=LCA(A,B),则可以分四种情况讨论

1.CA,CB 对于这种情况,只要起点在以A为根的子树中,终点在以B为根的子树中,都可以拿到这份宝藏,而子树A中的所有节点dfs序连续,子树B同理,于是我们可以用一个矩阵表示能取得该宝藏的所有方案。

2.C=A,AB 对于这种情况,需要先求出节点DD为路径(A,B)上最靠近A的节点,那么只要终点在子树B上,起点不在子树D上的路径,都可以拿到这份宝藏,而不在子树D上的点,可以用一个或者两个dfs序区间表示,因此可以用最多两个矩阵表示能取得该宝藏的所有方案。

3.C=B,AB 和情况2类似。

4.A=B 对于这种情况,若要求出所有经过节点A的路径,矩阵数目会是n2级别的,因此反过来思考,求出所有不包含节点A的路径,对于全部这种情况来说这样矩阵数目的级别为n。可以对答案先累加宝藏权值,然后对于所有不经过该点的矩阵减去这部分权值即可。

dfs序+扫描线(线段树)

#include<set>
#include<ctime>
#include<queue>
#include<cstdio>
#include<bitset>
#include<cctype>
#include<bitset>
#include<cstdlib>
#include<cassert>
#include<cstring>
#include<iostream>
#include<algorithm>
#define inf (1<<30)
#define INF (1ll<<62)
#define fi first
#define se second
#define rep(x,s,t) for(int x=s,t_=t;x<t_;x++)
#define per(x,s,t) for(int x=t-1,s_=s;x>=s_;x--)
#define prt(x) cout<<#x<<":"<<x<<" "
#define prtn(x) cout<<#x<<":"<<x<<endl
#define pc(x) putchar(x)
#define pb(x) push_back(x)
#define hash asfmaljkg
#define rank asfjhgskjf
#define y1 asggnja
#define y2 slfvm
using namespace std;
typedef long long ll;
typedef pair<int,int> ii;
template<class T>void sc(T &x){
    int f=1;char c;x=0;
    while(c=getchar(),c<48)if(c=='-')f=-1;
    do x=x*10+(c^48);
    while(c=getchar(),c>47);
    x*=f;
}
template<class T>void nt(T x){
    if(!x)return;
    nt(x/10);
    pc(x%10+'0');
}
template<class T>void pt(T x){
    if(x<0)pc('-'),x=-x;
    if(!x)pc('0');
    else nt(x);
}
template<class T>void ptn(T x){
    pt(x);putchar('\n');
}
template<class T>void pts(T x){
    pt(x);putchar(' ');
}
template<class T>inline void Max(T &x,T y){if(x<y)x=y;}
template<class T>inline void Min(T &x,T y){if(x>y)x=y;}

const int maxn=100005;
int n,m;
int lx[maxn],rx[maxn],dfs_clock;
int link[maxn];

int last[maxn],ecnt;
struct Edge{
    int to,nxt;
}e[maxn<<1];
inline void ins(int u,int v){
    e[ecnt]=(Edge){v,last[u]};
    last[u]=ecnt++;
}

int tot;
struct unit{
    int x,l,r,v;
    inline bool operator<(const unit&a)const{
        return x<a.x;
    }
}tar[maxn*3];

int sz[maxn],par[maxn],dep[maxn];
void assign(int x,int f){
    sz[x]=1;
    par[x]=f;
    dep[x]=dep[f]+1;

    for(int i=last[x];i!=-1;i=e[i].nxt){
        int to=e[i].to;
        if(to==f)continue;
        assign(to,x);
        sz[x]+=sz[to];
    }
}

void dfs(int x,int p){
    int mx=0;
    link[x]=p;
    lx[x]=rx[x]=++dfs_clock;

    for(int i=last[x];i!=-1;i=e[i].nxt){
        int to=e[i].to;
        if(to==par[x])continue;
        if(sz[to]>sz[mx])mx=to;
    }
    if(!mx)return;
    dfs(mx,p);
    for(int i=last[x];i!=-1;i=e[i].nxt){
        int to=e[i].to;
        if(to==par[x])continue;
        if(to!=mx)dfs(to,to);
    }
    rx[x]=dfs_clock;
}

int lca(int x,int y){
    while(link[x]!=link[y]){
        if(dep[link[x]]<dep[link[y]])swap(x,y);
        x=par[link[x]];
    }
    return dep[x]<dep[y]?x:y;
}

void add_rec(int a1,int a2,int b1,int b2,int val){
//  [a1,a2][b1,b2]
//  prt(a1);prt(a2);prt(b1);prt(b2);prtn(val);
    tar[++tot]=(unit){a1,b1,b2,val};
//  prtn(tar[tot].r);
    tar[++tot]=(unit){a2+1,b1,b2,-val};
//  prtn(tar[tot].r);
}

struct node{
    int mx,flag;
};

struct Segment{
    node v[maxn<<2];
    void down(int x){
        if(v[x].flag){
            adjust(x<<1,v[x].flag);
            adjust(x<<1|1,v[x].flag);
            v[x].flag=0;
        }
    }
    inline void up(int x){
        v[x].mx=max(v[x<<1].mx,v[x<<1|1].mx);
    }
    inline void adjust(int x,int flag){
        v[x].mx+=flag;
        v[x].flag+=flag;
    }
    void update(int l,int r,int x,int L,int R,int val){
        if(L<=l&&r<=R){
            adjust(x,val);
            return;
        }
        int mid=l+r>>1;
        down(x);
        if(L<=mid)update(l,mid,x<<1,L,R,val);
        if(R>mid)update(mid+1,r,x<<1|1,L,R,val);
        up(x);
    }
    void build(int l,int r,int x){
        v[x].mx=v[x].flag=0;
        if(l==r)return;
        int mid=l+r>>1;
        build(l,mid,x<<1);
        build(mid+1,r,x<<1|1);
    }
    int maximum(){
        return v[1].mx;
    }
}sgm;

void init(){
    memset(last,-1,n+1<<2);
    ecnt=0;
    dfs_clock=0;
    tot=0;
    sgm.build(1,n,1);
}
int all;
#define get got
int get(int x,int y){
    for(int i=last[x];i!=-1;i=e[i].nxt){
        int to=e[i].to;
        if(to==par[x])continue;
        if(lx[to]<=lx[y]&&rx[y]<=rx[to])
            return to;
    }
    return 0;
}
void update(int u,int v,int x){
    int w=lca(u,v);
    if(w!=u&&w!=v)
        add_rec(lx[u],rx[u],lx[v],rx[v],x);
    else if(w!=u){//w==v
        int k=get(v,u);
        if(rx[k]<n)add_rec(lx[u],rx[u],rx[k]+1,n,x);
        if(lx[k]>1)add_rec(lx[u],rx[u],1,lx[k]-1,x);
    }
    else if(w!=v){//w==u
        int k=get(u,v);
        if(rx[k]<n)add_rec(rx[k]+1,n,lx[v],rx[v],x);
        if(lx[k]>1)add_rec(1,lx[k]-1,lx[v],rx[v],x);
    }
    else{
        all+=x;
        for(int i=last[u];i!=-1;i=e[i].nxt){
            int to=e[i].to;
            if(to==par[u])continue;
            add_rec(lx[to],rx[to],lx[to],rx[to],-x);
        }
        if(lx[u]>1)add_rec(1,lx[u]-1,1,lx[u]-1,-x);
        if(rx[u]<n)add_rec(rx[u]+1,n,rx[u]+1,n,-x);
        if(lx[u]>1&&rx[u]<n){
            add_rec(1,lx[u]-1,rx[u]+1,n,-x);
            add_rec(rx[u]+1,n,1,lx[u]-1,-x);
        }
    }
}

int ans;
void work(){
    ans=-inf;
    sort(tar+1,tar+tot+1);
    int top=1;
    rep(i,1,n+1){
        while(top<=tot&&tar[top].x==i){
            int l=tar[top].l;
            int r=tar[top].r;
            int v=tar[top].v;
            sgm.update(1,n,1,l,r,v);
            top++;
        }
        Max(ans,sgm.maximum());
    }
}

void solve(){
    sc(n);sc(m);
    init();
    int u,v;
    rep(i,1,n){
        sc(u);sc(v);
        ins(u,v);
        ins(v,u);
    }
    assign(1,0);
    dfs(1,1);

    int w;
    all=0;
    rep(i,0,m){
        sc(u);sc(v);sc(w);
        update(u,v,w);
    }
    work();
    ptn(ans+all);
}
int main(){
//  freopen("pro.in","r",stdin);
//  freopen("pro.out","w",stdout);
    int cas;sc(cas);
    rep(kase,1,cas+1){
        printf("Case #%d: ",kase);
        solve();
    }
    return 0;
}
内容概要:本文设计了一种基于PLC的全自动洗衣机控制系统内容概要:本文设计了一种,采用三菱FX基于PLC的全自动洗衣机控制系统,采用3U-32MT型PLC作为三菱FX3U核心控制器,替代传统继-32MT电器控制方式,提升了型PLC作为系统的稳定性与自动化核心控制器,替代水平。系统具备传统继电器控制方式高/低水,实现洗衣机工作位选择、柔和过程的自动化控制/标准洗衣模式切换。系统具备高、暂停加衣、低水位选择、手动脱水及和柔和、标准两种蜂鸣提示等功能洗衣模式,支持,通过GX Works2软件编写梯形图程序,实现进洗衣过程中暂停添加水、洗涤、排水衣物,并增加了手动脱水功能和、脱水等工序蜂鸣器提示的自动循环控制功能,提升了使用的,并引入MCGS组便捷性与灵活性态软件实现人机交互界面监控。控制系统通过GX。硬件设计包括 Works2软件进行主电路、PLC接梯形图编程线与关键元,完成了启动、进水器件选型,软件、正反转洗涤部分完成I/O分配、排水、脱、逻辑流程规划水等工序的逻辑及各功能模块梯设计,并实现了大形图编程。循环与小循环的嵌; 适合人群:自动化套控制流程。此外、电气工程及相关,还利用MCGS组态软件构建专业本科学生,具备PL了人机交互C基础知识和梯界面,实现对洗衣机形图编程能力的运行状态的监控与操作。整体设计涵盖了初级工程技术人员。硬件选型、; 使用场景及目标:I/O分配、电路接线、程序逻辑设计及组①掌握PLC在态监控等多个方面家电自动化控制中的应用方法;②学习,体现了PLC在工业自动化控制中的高效全自动洗衣机控制系统的性与可靠性。;软硬件设计流程 适合人群:电气;③实践工程、自动化及相关MCGS组态软件与PLC的专业的本科生、初级通信与联调工程技术人员以及从事;④完成PLC控制系统开发毕业设计或工业的学习者;具备控制类项目开发参考一定PLC基础知识。; 阅读和梯形图建议:建议结合三菱编程能力的人员GX Works2仿真更为适宜。; 使用场景及目标:①应用于环境与MCGS组态平台进行程序高校毕业设计或调试与运行验证课程项目,帮助学生掌握PLC控制系统的设计,重点关注I/O分配逻辑、梯形图与实现方法;②为工业自动化领域互锁机制及循环控制结构的设计中类似家电控制系统的开发提供参考方案;③思路,深入理解PL通过实际案例理解C在实际工程项目PLC在电机中的应用全过程。控制、时间循环、互锁保护、手动干预等方面的应用逻辑。; 阅读建议:建议结合三菱GX Works2编程软件和MCGS组态软件同步实践,重点理解梯形图程序中各环节的时序逻辑与互锁机制,关注I/O分配与硬件接线的对应关系,并尝试在仿真环境中调试程序以加深对全自动洗衣机控制流程的理解。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值