zoukankan      html  css  js  c++  java
  • BZOJ 3037 创世纪

     题解:

     首先从基环树上的环上选两个点x,y

     断开x,y之间的边,然后做树形DP.

     设f[x]为选x的情况下的最大值,g[x]为不选x的情况下的最大值.

     分两种情况讨论,

     1.选x,则y一开始就处于被支配状态,在计算y的f[]函数值时需要特判.

     2.不选x,按正常DP做即可.

     1 #include<cstdio>
     2 #include<vector>
     3 using namespace std;
     4 #define ll long long
     5 #define FILE "dealing"
     6 #define up(i,j,n) for(int i=j;i<=n;i++)
     7 #define db long double 
     8 #define pii pair<int,int>
     9 #define pb push_back
    10 #define mem(a,L) memset(a,0,sizeof(int)*(L+1))
    11 template<class T> inline bool cmin(T& a,T b){return a>b?a=b,true:false;}
    12 template<class T> inline bool cmax(T& a,T b){return a<b?a=b,true:false;}
    13 template<class T> inline T squ(T a){return a*a;}
    14 const ll maxn=2000100+10,inf=1e9+10,limit=1e7;
    15 int read(){
    16     int x=0,f=1,ch=getchar();
    17     while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
    18     while(ch>='0'&&ch<='9')x=(x<<1)+(x<<3)+ch-'0',ch=getchar();
    19     return x*f;
    20 }
    21 int n;
    22 vector<int> t[maxn];
    23 int f[maxn],g[maxn],to[maxn];
    24 int vis[maxn];
    25 int rt,rt2,q[maxn],top=0;
    26 void dfs(int x){
    27     q[++top]=x;
    28     vis[x]=1;
    29     if(!vis[to[x]])dfs(to[x]);
    30     else {
    31         rt=x;
    32         rt2=to[x];
    33     }
    34 }
    35 void dfs2(int x){
    36     vis[x]=1;
    37     for(int i=0;i<t[x].size();i++)
    38         if(!vis[t[x][i]])dfs2(t[x][i]);
    39     if(!vis[to[x]])dfs2(to[x]);
    40 }
    41 //f[x] 选 g[x] 不选
    42 int flag=0;
    43 void dfs1(int x){//选rt
    44     f[x]=1,g[x]=0;int Max=-inf;
    45     for(int i=0;i<t[x].size();i++){
    46         int y=t[x][i];if((x==rt2&&y==rt))continue;
    47         dfs1(y);
    48         f[x]+=f[y];
    49         g[x]+=f[y];
    50         cmax(Max,g[y]-f[y]);
    51     }
    52     f[x]+=Max;
    53     if(x==rt2&&flag)f[x]-=Max;
    54     cmax(f[x],0);
    55 }
    56 
    57 int main(){
    58     freopen(FILE".in","r",stdin);
    59     freopen(FILE".out","w",stdout);
    60     n=read();
    61     up(i,1,n){
    62         to[i]=read();
    63         t[to[i]].push_back(i);
    64     }
    65     int ans=0;
    66     up(i,1,n){
    67         if(vis[i])continue;
    68         top=0;dfs(i);
    69         while(top)vis[q[top--]]=0;
    70         dfs2(i);
    71         int Ans=0;
    72         flag=1;
    73         dfs1(rt);
    74         cmax(Ans,g[rt]);
    75         flag=0;
    76         dfs1(rt);
    77         cmax(Ans,f[rt]);
    78         ans+=Ans;
    79     }
    80     printf("%d
    ",ans);
    81     return 0;
    82 }
    View Code
  • 相关阅读:
    mongodb修改bindIp和启动关闭
    把eclipse上的web项目导入IDEA
    项目重构也许更好——《梦断代码》读后感
    安卓记账本开发——数据库创建和数据测试
    开源的魅力——《梦断代码》读后感
    GitHub 网站上不去/加载慢/加载不全 解决办法
    安卓记账本开发——适配器编写和测试
    上传和下载
    cookie
    分页sql
  • 原文地址:https://www.cnblogs.com/chadinblog/p/6807316.html
Copyright © 2011-2022 走看看