zoukankan      html  css  js  c++  java
  • 1389. Roadworks 夜

    http://acm.timus.ru/problem.aspx?space=1&num=1389

    一维树形DP 不难 关键在于输出类似路径的选择

    求完最优答案 再顺着答案走一遍就可以了

    关键:

    从一个节点出发的各条 road 中 如果某一条 road 被 block 则相连的下一个节点开始的路都不能进行 block

    如果某一条路没有被 block 则相连下一个节点开始的路可以进行选择性的是否 block

    但要注意从一个点出发的 road 最多只能有一个block

    代码及其注释:

    #include <iostream>
    #include <cstdio>
    #include <cstring>
    #include <queue>
    #include <vector>
    #include <algorithm>
    
    #define LL long long
    //#pragma comment(linker, "/STACK:1024000000,1024000000")
    using namespace std;
    const int N=100005;
    int head[N],I;
    struct node
    {
        int j,next;
        int k;
    }side[N*2];
    struct node1
    {
        int l,r;
        bool blocked;
    }road[N];//输入的路 blocked 代表是否 被堵
    int block[N];//以此节点为根的树 从根节点出发的路有一条被堵的最优结果
    int select[N];//对应被堵的路是哪一条
    int noblock[N];//以此节点为根的树 从根节点出发的路没有被堵的最优结果
    void build(int i,int j,int k)
    {
        side[I].j=j;
        side[I].k=k;
        side[I].next=head[i];
        head[i]=I++;
    }
    int dpblock(int x,int pre);
    int dpnoblock(int x,int pre)
    {
        if(noblock[x]!=-1)
        return noblock[x];
        noblock[x]=0;
        for(int t=head[x];t!=-1;t=side[t].next)
        {
            int l=side[t].j;
            if(l==pre)
            continue;
            noblock[x]+=max(dpnoblock(l,x),dpblock(l,x));//以往下节点开始的路 既可以堵也可以不堵
        }
        return noblock[x];
    
    }
    int dpblock(int x,int pre)
    {
        if(block[x]!=-1)
        return block[x];
        block[x]=0;
        int temp=-1,w=-1;
        for(int t=head[x];t!=-1;t=side[t].next)
        {
            int l=side[t].j;
            if(l==pre)
            continue;
            block[x]+=max(dpnoblock(l,x),dpblock(l,x));
            if(temp==-1||(noblock[l]-max(noblock[l],block[l]))>(noblock[temp]-max(noblock[temp],block[temp])))
            {temp=l;w=side[t].k;}//对哪条路堵 进行取舍
        }
        if(temp==-1)//注意叶子节点情况
        return block[x];
        block[x]+=(noblock[temp]-max(noblock[temp],block[temp]))+1;
        select[x]=w;
        return block[x];
    }
    void dfsnoblock(int x,int pre);
    void dfsblock(int x,int pre)//根据最优路径 标记答案
    {
        if(select[x]!=-1)
        road[select[x]].blocked=true;
        for(int t=head[x];t!=-1;t=side[t].next)
        {
            int l=side[t].j;
            if(l==pre)
            continue;
            if(side[t].k==select[x])
            {dfsnoblock(l,x);continue;}
            if(block[l]>noblock[l])
            dfsblock(l,x);
            else
            dfsnoblock(l,x);
        }
    }
    void dfsnoblock(int x,int pre)//根据最优路径 标记答案
    {
        for(int t=head[x];t!=-1;t=side[t].next)
        {
            int l=side[t].j;
            if(l==pre)
            continue;
            if(block[l]>noblock[l])
            dfsblock(l,x);
            else
            dfsnoblock(l,x);
        }
    }
    int main()
    {
        //freopen("data.txt","r",stdin);
        int n,m;
        while(scanf("%d %d",&n,&m)!=EOF)
        {
            memset(head,-1,sizeof(head));
            I=0;
            for(int i=1;i<=m;++i)
            {
                scanf("%d %d",&road[i].l,&road[i].r);
                build(road[i].l,road[i].r,i);
                build(road[i].r,road[i].l,i);
            }
            memset(block,-1,sizeof(block));
            memset(noblock,-1,sizeof(noblock));
            memset(select,-1,sizeof(select));
            printf("%d\n",max(dpblock(1,-1),dpnoblock(1,-1)));
            for(int i=1;i<=m;++i)
            road[i].blocked=false;
            if(block[1]>noblock[1])
            dfsblock(1,-1);
            else
            dfsnoblock(1,-1);
            for(int i=1;i<=m;++i)
            {
                if(road[i].blocked==true)
                printf("%d %d\n",road[i].l,road[i].r);
            }
        }
        return 0;
    }
    
    
  • 相关阅读:
    JAVA规范
    JMS开发指南
    JMS异步消息机制
    大型系统中使用JMS优化技巧–Sun OpenMQ
    02.MyBatis配置文件详解
    elasticsearch.yml配置文件
    04.ActiveMQ与Spring JMS整合
    01.MyBatis入门
    03.JMS深入
    02.JMS基础
  • 原文地址:https://www.cnblogs.com/liulangye/p/2697854.html
Copyright © 2011-2022 走看看