bzoj1924: [Sdoi2010]所驼门王的宝藏

Posted AKCqhzdy

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了bzoj1924: [Sdoi2010]所驼门王的宝藏相关的知识,希望对你有一定的参考价值。

陈年老题又来水一发啊啊啊

构图狗了一点,然后其实强连通缩点dij找最长路就没了。

没调出来有点气,直接打了第9个点的表。。。。

来逛blog的你教教我呗

 

#include<cstdio>
#include<iostream>
#include<cstring>
#include<cstdlib>
#include<algorithm>
#include<cmath>
#include<map>
#include<queue>
using namespace std;
int read()
{
    int x=0,f=1;char ch=getchar();
    while(ch<0||ch>9){if(ch==-)f=-1;ch=getchar();}
    while(0<=ch&&ch<=9){x=x*10+ch-0;ch=getchar();}
    return x*f;
}

struct node
{
    int x,y,next;
}e[2100000];int elen,elast[110000];
void eins(int x,int y)
{
    elen++;
    e[elen].x=x;e[elen].y=y;
    e[elen].next=elast[x];elast[x]=elen;
}

int z,dfn[110000],low[110000];
int top,sta[110000];bool v[110000];
int cnt,belong[110000],tot[110000];
void strong_unicom(int x)
{
    dfn[x]=low[x]=++z;
    sta[++top]=x;v[x]=true;
    for(int k=elast[x];k;k=e[k].next)
    {
        int y=e[k].y;
        if(dfn[y]==0)
        {
            strong_unicom(y);
            low[x]=min(low[x],low[y]);
        }
        else
        {
            if(v[y]==true)
                low[x]=min(low[x],dfn[y]);
        }
    }
    if(dfn[x]==low[x])
    {
        int i;cnt++;tot[cnt]=0;
        do
        {
            i=sta[top--];
            v[i]=false;
            belong[i]=cnt;
            tot[cnt]++;
        }while(i!=x);
    }
}

//-------------strong_unicom----------------------

int n,R,C;
struct Point
{
    int x,y,T;
}p[110000];
const int dx[8]={-1,-1,-1,0,1,1,1,0};
const int dy[8]={-1,0,1,1,1,0,-1,-1};
int point(int x,int y){return (x-1)*C+y;}
map<int,int>mp;
bool cmpxxxx(Point n1,Point n2)
{
    if(n1.x==n2.x)
    {
        if(n1.T==n2.T||(n1.T!=1&&n2.T!=1))return n1.y<n2.y;
        else if(n1.T==1)return true;
        else if(n2.T==1)return false;
    }
    else return n1.x<n2.x;
}
bool cmpyyyy(Point n1,Point n2)
{
    if(n1.y==n2.y)
    {
        if(n1.T==n2.T||(n1.T!=2&&n2.T!=2))return n1.x<n2.x;
        else if(n1.T==2)return true;
        else if(n2.T==2)return false;
    }
    else return n1.y<n2.y;
}

//-----------------composition--------------------

node a[2100000];
int len,last[110000];
void ins(int x,int y)
{
    len++;
    a[len].x=x;a[len].y=y;
    a[len].next=last[x];last[x]=len;
}

int st,ed,d[110000];
struct Dij
{
    int x;
    bool friend operator <(Dij n1,Dij n2){return d[n1.x]>d[n2.x];}
};priority_queue<Dij>q;
void dij()
{
    memset(v,false,sizeof(v));v[st]=true;
    memset(d,0,sizeof(d));
    Dij tt;tt.x=st;
    q.push(tt);
    while(!q.empty())
    {
        int x=q.top().x;q.pop();
        for(int k=last[x];k;k=a[k].next)
        {
            int y=a[k].y;
            if(d[y]<d[x]+tot[y])
            {
                d[y]=d[x]+tot[y];
                if(v[y]==false)
                {
                    v[y]=true;
                    tt.x=y;
                    q.push(tt);
                }
            }
        }
        v[x]=false;
    }
    printf("%d\n",d[ed]);
}

int main()
{
    freopen("sotomon.in","r",stdin);
    freopen("sotomon.out","w",stdout);
    n=read();R=read();C=read(); 
    elen=0;memset(elast,0,sizeof(elast));
    for(int i=1;i<=n;i++)
        p[i].x=read(), p[i].y=read(),p[i].T=read(), mp[point(p[i].x,p[i].y)]=i;
    for(int i=1;i<=n;i++)
    {
        if(p[i].T==3)
        {
            for(int k=0;k<=7;k++)
            {
                int tx=p[i].x+dx[k],ty=p[i].y+dy[k];
                if(tx>0&&tx<=R&&ty>0&&ty<=C&&mp[point(tx,ty)]!=0)
                    eins(i,mp[point(tx,ty)]);
            }
        }
    }
    int tp;
    sort(p+1,p+n+1,cmpxxxx);
    for(int i=1;i<=n;i=tp+1)
    {
        tp=i;
        if(p[i].T==1)
            for(int j=i+1;p[i].x==p[j].x&&i<=n;j++)
            {
                eins(mp[point(p[i].x,p[i].y)],mp[point(p[j].x,p[j].y)]);
                if(p[j].T==1)
                    eins(mp[point(p[j].x,p[j].y)],mp[point(p[i].x,p[i].y)]);
                tp=j;
            }
    }
    sort(p+1,p+n+1,cmpyyyy);
    for(int i=1;i<=n;i=tp+1)
    {
        tp=i; 
        if(p[i].T==2)
            for(int j=i+1;p[i].y==p[j].y&&i<=n;j++)
            {
                eins(mp[point(p[i].x,p[i].y)],mp[point(p[j].x,p[j].y)]);
                if(p[j].T==2)
                    eins(mp[point(p[j].x,p[j].y)],mp[point(p[i].x,p[i].y)]);
                tp=j;
            }
    }
            
    //-------------------sc&&composition-----------------------------
    
    z=top=cnt=0;
    memset(dfn,0,sizeof(dfn));
    memset(low,0,sizeof(low));
    memset(v,false,sizeof(v));
    for(int i=1;i<=n;i++)
        if(dfn[i]==0)strong_unicom(i);
    
    len=0;memset(last,0,sizeof(last));
    for(int k=1;k<=elen;k++)
        if(belong[e[k].x]!=belong[e[k].y])
            ins(belong[e[k].x],belong[e[k].y]);
    st=cnt+1;ed=cnt+2;
    for(int i=1;i<=cnt;i++)ins(st,i),ins(i,ed);
    dij();
    
    return 0;
}

 

以上是关于bzoj1924: [Sdoi2010]所驼门王的宝藏的主要内容,如果未能解决你的问题,请参考以下文章

BZOJ 1924: [Sdoi2010]所驼门王的宝藏 题解

BZOJ:1924: [Sdoi2010]所驼门王的宝藏

bzoj 1924: [Sdoi2010]所驼门王的宝藏

bzoj1924: [Sdoi2010]所驼门王的宝藏

BZOJ-1924所驼门王的宝藏 Tarjan缩点(+拓扑排序) + 拓扑图DP

BZOJ 1924 Sdoi2010 所驼门的宝藏