Java教程

洛谷P2607 [ZJOI2008] 骑士

本文主要是介绍洛谷P2607 [ZJOI2008] 骑士,对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!

在做这道题之前,可以先去看一下:

P1453 城市环路: https://www.cnblogs.com/liyishui2003/p/16150985.html

如果说城市环路是没有上司的舞会的基环树版本

那P2607就是城市环路的基环树森林版本

刚开始开开心心把城市环路的代码改了改输出输入就交了,wa,20tps

挠头,想了想,唉,它没有保证联通哎!那就是一片基环树森林,再加一个col数组表示有没有被查过就好了

注意:这种求和,累加的题目,不开longlong..就..

#include<bits/stdc++.h>
using namespace std;
const int maxn=int(1e6)+7;
int col[maxn],vis[maxn],vis2[maxn],n,p[maxn],head[maxn],cnt=0,s,t,isfind=0,tree=0;
long long finalans=0,ans=0,dp[maxn][3];
double k;
struct lys{
    int from,to,nxt;
}e[maxn*3];
void add(int from,int to)
{
    cnt++;e[cnt].from=from;e[cnt].to=to;e[cnt].nxt=head[from];head[from]=cnt;
}
void build(int u,int fa)
{ col[u]=tree;
  vis[u]=1;

    for(int i=head[u];i;i=e[i].nxt)
    {
        int to=e[i].to;
        if(to==fa) continue;
        if(vis[to]==1) 
        {
            s=to;t=u;continue;
        }
        build(to,u);
    }
}
void dfs(int fa,int u)
{ vis[u]=1;
  dp[u][0]=0;
  dp[u][1]=p[u];
    for(int i=head[u];i;i=e[i].nxt)
    {
        int to=e[i].to;
        if(to==fa||vis[to]) continue;
        dfs(u,to);
        dp[u][0]+=max(dp[to][0],dp[to][1]);
        dp[u][1]+=dp[to][0];
    }
}
int main()
{ 
    //freopen("lys.in","r",stdin);
   cin>>n;
   for(int i=1;i<=n;i++)
   {int v;
        cin>>p[i]>>v;
        add(i,v);
        add(v,i);
   }    

   for(int i=1;i<=n;i++)
   {
        if(!col[i]) 
        {  tree++;
           ans=0;
           memset(vis,0,sizeof(vis));
            build(i,-1);
            memset(vis,0,sizeof(vis));
            dfs(-1,s);
            ans=dp[s][0];
            memset(vis,0,sizeof(vis));
            dfs(-1,t);
            ans=max(ans,dp[t][0]);
        finalans+=ans;
     }
   }

   printf("%lld",finalans);
}

 

这篇关于洛谷P2607 [ZJOI2008] 骑士的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!