BZOJ 1040 骑士

Posted on 2017-03-19 13:14  ziliuziliu  阅读(109)  评论(0编辑  收藏  举报

突然发现上题的写法有点问题啊。。。。

仿佛应该是枚举这多的这条边的两个端点分别是什么状态。

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<queue>
#define maxv 1000050
#define inf 0x7f7f7f7f7f7f7f7fLL
using namespace std;
long long n,a[maxv],dx[maxv],dy[maxv],dp[maxv][3],cnt=0,father[maxv],ans=0,w[maxv];
struct pnt
{
    long long id,father,rank;
}p[maxv];
struct edge
{
    long long x,y,father,root;
}e[maxv];
queue <long long> q;
long long read()
{
    char ch;long long data=0;
    while (ch<'0' || ch>'9') ch=getchar();
    while (ch>='0' && ch<='9') 
    {
        data=data*10+ch-'0';
        ch=getchar();
    }
    return data;
}
bool cmp1(pnt x,pnt y)
{
    if (x.father!=y.father) return x.father<y.father;
    return x.rank<y.rank;
}
bool cmp2(edge x,edge y) {return x.father<y.father;}
long long getfather(long long x)
{
    if (father[x]==x) return x;
    father[x]=getfather(father[x]);return father[x];
}
void topu_sort()
{
    for (long long i=1;i<=n;i++)
    {
        if (!dy[i]) q.push(i);
        p[i].father=getfather(i);
    }
    while (!q.empty())
    {
        long long head=q.front();q.pop();
        dy[a[head]]--;if (!dy[a[head]]) {p[a[head]].rank=p[head].rank+1;q.push(a[head]);}
    }
    sort(p+1,p+n+1,cmp1);sort(e+1,e+cnt+1,cmp2);
}
void tree_dp(long long l,long long r,long long x,long long type)
{
    for (long long i=l;i<=r;i++) dp[p[i].id][1]=dp[p[i].id][2]=0;
    long long i;
    for (i=l;!p[i].rank;i++)
    {
        long long v=p[i].id;
        if (v!=x) {dp[v][1]=0;dp[v][2]=w[v];}
        else
        {
            if (type!=2) {dp[v][1]=0;dp[v][2]=-inf;}
            else {dp[v][1]=-inf;dp[v][2]=w[v];}
        }
        if (v!=a[v])
        {
            dp[a[v]][1]+=max(dp[v][1],dp[v][2]);
            dp[a[v]][2]+=dp[v][1];
        }
    }
    for (;i<=r;i++)
    {
        long long v=p[i].id;
        if (v!=x) dp[v][2]+=w[v];
        else
        {
            if (type!=2) dp[v][2]=-inf;
            else {dp[v][1]=-inf;dp[v][2]+=w[v];}
        }
        if (v!=a[v])
        {
            dp[a[v]][1]+=max(dp[v][1],dp[v][2]);
            dp[a[v]][2]+=dp[v][1];
        }
    }
}
int main()
{ 
    n=read();for (long long i=1;i<=n;i++) {father[i]=i;p[i].id=i;}
    for (long long i=1;i<=n;i++)
    {
        w[i]=read();a[i]=read();
        long long f1=getfather(i),f2=getfather(a[i]);
        if (f1==f2) {e[++cnt].x=i;e[cnt].y=a[i];}
        else {dx[i]++;dy[a[i]]++;father[f1]=f2;}
    }
    for (long long i=1;i<=cnt;i++) e[i].father=getfather(e[i].x); 
    topu_sort();
    long long l=1,r=1,ret=0;
    while (l<=n)
    {
        long long mx=0;r=l;while (p[r+1].father==p[l].father) r++;
        long long i;ret++;
        tree_dp(l,r,e[ret].y,1);mx=max(mx,dp[e[ret].x][1]);
        tree_dp(l,r,e[ret].y,2);mx=max(mx,dp[e[ret].x][1]);
        tree_dp(l,r,e[ret].y,3);mx=max(mx,dp[e[ret].x][2]);
        ans+=mx;l=r+1;
    }
    printf("%lld\n",ans);
    return 0;
}