• bzoj1040[ZJOI2008]骑士


    bzoj1040[ZJOI2008]骑士

    题意:

    n个骑士,每个骑士都有且仅有一个自己最厌恶的骑士(当然不是他自己),且有一个战斗力。求从所有的骑士中选出一个骑士之间没有矛盾的骑士军团最大战斗力之和。n最大10e6

    题解:

    厌恶关系实际上是无向的。从每个骑士出发,沿着关系走可以得一个基环树(就是只有一个环,且断了环就会变成一棵树的连通块)。于是先dfs找环,然后断环,分别尝试以去掉的那条边的两个节点u,v为根,作树形dp,将f[u][0]与f[v][0]的最大值计入答案。

    代码:

     1 #include <cstdio>
     2 #include <cstring>
     3 #include <algorithm>
     4 #define inc(i,j,k) for(int i=j;i<=k;i++)
     5 #define maxn 1000010
     6 #define ll long long
     7 using namespace std;
     8 
     9 bool vis[maxn]; ll f[maxn][2],w[maxn]; int n,bad;
    10 struct e{int f,t,n;}; e es[maxn*2]; int ess,g[maxn];
    11 void pe(int f,int t){
    12     es[++ess]=(e){f,t,g[f]}; g[f]=ess; es[++ess]=(e){t,f,g[t]}; g[t]=ess;
    13 }
    14 void dfs(int x,int fa){
    15     vis[x]=1;
    16     for(int i=g[x];i!=-1;i=es[i].n)if(i!=fa){
    17         if(vis[es[i].t])bad=i;else dfs(es[i].t,i^1);
    18     }
    19 }
    20 ll dp(int x,int fa,int b){
    21     if(f[x][b]!=-1)return f[x][b]; f[x][b]=0; //printf("%d %d %d %d %d
    ",x,fa,b,f[x][b]);
    22     for(int i=g[x];i!=-1;i=es[i].n)if(i!=fa&&i!=bad&&i!=(bad^1)){
    23         if(!b)f[x][b]+=max(dp(es[i].t,i^1,0),dp(es[i].t,i^1,1)+w[es[i].t]);
    24         else f[x][b]+=dp(es[i].t,i^1,0);
    25     }
    26     return f[x][b];
    27 }
    28 int main(){
    29     scanf("%d",&n); memset(vis,0,sizeof(vis)); ll ans=0; memset(g,-1,sizeof(g)); ess=-1;
    30     inc(i,1,n){ll a; int b; scanf("%lld%d",&a,&b); w[i]=a; pe(i,b);}
    31     inc(i,1,n)if(!vis[i]){
    32         dfs(i,-1); ll mx=0;
    33         memset(f,-1,sizeof(f)); mx=max(mx,dp(es[bad].f,-1,0));
    34         memset(f,-1,sizeof(f)); mx=max(mx,dp(es[bad].t,-1,0));
    35         ans+=mx;
    36     }
    37     printf("%lld",ans);
    38 }

    20160519

  • 相关阅读:
    [置顶] 文件批量重命名(工具)
    zookeeper源码分析之三客户端发送请求流程
    java set转list,数组与list的转换
    分布式电子邮件系统设计--转载
    redis 模糊删除实现
    eclipse 使用jetty调试时,加依赖工程的源码调试方法
    社交产品后端架构设计--转载
    solr服务器的查询过程
    What is corresponding Cron expression to fire in every X seconds, where X > 60? --转载
    zookeeper源码分析之二客户端启动
  • 原文地址:https://www.cnblogs.com/YuanZiming/p/5732678.html
Copyright © 2020-2023  润新知