• [BZOJ 1040][ZJOI2008]骑士


    1040: [ZJOI2008]骑士

    Time Limit: 10 Sec  Memory Limit: 162 MB
    Submit: 5403  Solved: 2060
    [Submit][Status][Discuss]

    Description

      Z国的骑士团是一个很有势力的组织,帮会中汇聚了来自各地的精英。他们劫富济贫,惩恶扬善,受到社会各
    界的赞扬。最近发生了一件可怕的事情,邪恶的Y国发动了一场针对Z国的侵略战争。战火绵延五百里,在和平环境
    中安逸了数百年的Z国又怎能抵挡的住Y国的军队。于是人们把所有的希望都寄托在了骑士团的身上,就像期待有一
    个真龙天子的降生,带领正义打败邪恶。骑士团是肯定具有打败邪恶势力的能力的,但是骑士们互相之间往往有一
    些矛盾。每个骑士都有且仅有一个自己最厌恶的骑士(当然不是他自己),他是绝对不会与自己最厌恶的人一同出
    征的。战火绵延,人民生灵涂炭,组织起一个骑士军团加入战斗刻不容缓!国王交给了你一个艰巨的任务,从所有
    的骑士中选出一个骑士军团,使得军团内没有矛盾的两人(不存在一个骑士与他最痛恨的人一同被选入骑士军团的
    情况),并且,使得这支骑士军团最具有战斗力。为了描述战斗力,我们将骑士按照1至N编号,给每名骑士一个战
    斗力的估计,一个军团的战斗力为所有骑士的战斗力总和。

    Input

      第一行包含一个正整数N,描述骑士团的人数。接下来N行,每行两个正整数,按顺序描述每一名骑士的战斗力
    和他最痛恨的骑士。

    Output

      应包含一行,包含一个整数,表示你所选出的骑士军团的战斗力。

    Sample Input

    3
    10 2
    20 3
    30 1

    Sample Output

    30

    HINT

    N ≤ 1 000 000,每名骑士的战斗力都是不大于 1 000 000的正整数。

    题解

    分析题意可以得到这应该是个最大权独立集...

    然而普适的最大权独立集问题并不可做...这个问题肯定有特殊的地方. 我们发现每个点主动连出去的边有且仅有一条, 我们可以发现这是个环套树.

    如果是树的话直接一个 $DP$ 怼上去就可以了, 而对于环套树, 我们可以先进行一遍 $DFS$ 找找是否有环, 没有环直接按树来 $DP$ , 如果有环的话, 任意选一条边断掉转化成树, 标记这条边连接的两个结点, 两个结点中强制某一个不能选, $DP$ 一遍, 换另一个结点强制不选再跑一遍, 在两种情况下取最大值.

    断边的过程可以通过维护全局标记实现, 对于与全局标记相等的边直接不走就可以了, 对于强制不选, 则可以在跑一遍 $DP$ 后强行将强制不选的那个结点选中时得到的最大值赋为 $-infty$ 即可

    参考代码

    GitHub

     1 #include <cstdio>
     2 #include <cstring>
     3 #include <climits>
     4 #include <cstdlib>
     5 #include <iostream>
     6 #include <algorithm>
     7 
     8 const int MAXN=1e6+10;
     9 
    10 struct Edge{
    11     int from;
    12     int to;
    13     int ID;
    14     Edge* next;
    15 };
    16 Edge E[MAXN*2];
    17 Edge* head[MAXN];
    18 Edge* top=E;
    19 
    20 int n;
    21 int disableV;
    22 int disableE;
    23 int cut1,cut2;
    24 long long ans,tmp;
    25 bool visited[MAXN];
    26 long long val[MAXN];
    27 long long dp[MAXN][2];
    28 
    29 void DP(int,int);
    30 void DFS(int,int);
    31 void Initialize();
    32 void Insert(int,int,int);
    33 
    34 int main(){
    35     Initialize();
    36     for(int i=1;i<=n;i++){
    37         if(visited[i])
    38             continue;
    39         else{
    40             DFS(i,0);
    41             disableV=cut1;
    42             DP(i,0);
    43             tmp=std::max(dp[i][0],dp[i][1]);
    44             disableV=cut2;
    45             DP(i,0);
    46             tmp=std::max(tmp,std::max(dp[i][0],dp[i][1]));
    47             ans+=tmp;
    48         }
    49     }
    50     printf("%lld
    ",ans);
    51     return 0;
    52 }
    53 
    54 void DFS(int root,int prt){
    55     visited[root]=true;
    56     for(Edge* i=head[root];i!=NULL;i=i->next){
    57         if(i->ID==prt)
    58             continue;
    59         else if(visited[i->to]){
    60             cut1=root;
    61             cut2=i->to;
    62             disableE=i->ID;
    63         }
    64         else
    65             DFS(i->to,i->ID);
    66     }
    67 }
    68 
    69 void DP(int root,int prt){
    70     dp[root][0]=0;
    71     dp[root][1]=val[root];
    72     for(Edge* i=head[root];i!=NULL;i=i->next){
    73         if(i->ID==disableE||i->ID==prt)
    74             continue;
    75         DP(i->to,i->ID);
    76         dp[root][0]+=std::max(dp[i->to][0],dp[i->to][1]);
    77         dp[root][1]+=dp[i->to][0];
    78     }
    79     if(root=disableV)
    80         dp[root][1]=LLONG_MIN;
    81 }
    82 
    83 void Initialize(){
    84     scanf("%d",&n);
    85     int tmp;
    86     for(int i=1;i<=n;i++){
    87         scanf("%d%d",val+i,&tmp);
    88         Insert(i,tmp,i);
    89         Insert(tmp,i,i);
    90     }
    91 }
    92 
    93 inline void Insert(int from,int to,int ID){
    94     top->to=to;
    95     top->ID=ID;
    96     top->from=from;
    97     top->next=head[from];
    98     head[from]=top++;
    99 }
    Backup

     

  • 相关阅读:
    iptables命令参数简介
    在linux下开启IP转发的方法
    Linux配置IP路由
    NAT转换
    JS实验案例
    Ubuntu kylin优麒麟root用户与静态网络设置
    非对称加密-RSA
    对称加密-DES
    DM5详解
    Visio的安装教程
  • 原文地址:https://www.cnblogs.com/rvalue/p/7684069.html
Copyright © 2020-2023  润新知