1924: [Sdoi2010]所驼门王的宝藏 tarjan缩点+dp最长路

来源:互联网 发布:数据科学中的r语言 编辑:程序博客网 时间:2024/06/06 03:55

读完题感觉很是凌乱,看到数据范围又一阵冷汗,仔细看一下题,其实就是给你了点之间的关系,建边后先缩一下点,重建图后dp一下就好了。
好吧用了一下stl。。

#include<iostream>#include<cstdio>#include<vector>#include<map>#define N 1000005using namespace std;int n,r,c,st,cnt,cnt0,tot,scc,top,ans;int x[N],y[N],opt[N],dfn[N],low[N],stack[N],head[N],head0[N],belong[N],num[N],deep[N];int next[N],next0[N],list[N],list0[N];bool inset[N],v[N];vector <int> a[N],b[N];map <int,int> mp[N];int dx[8]={-1,-1,-1,0,1,1,1,0};int dy[8]={-1,0,1,1,1,0,-1,-1};inline int read(){    int a=0,f=1; char c=getchar();    while (c<'0'||c>'9') {if (c=='-') f=-1; c=getchar();}    while (c>='0'&&c<='9') {a=a*10+c-'0'; c=getchar();}    return a*f;}inline void insert(int x,int y){    next[++cnt]=head[x];    head[x]=cnt;    list[cnt]=y;}inline void insert0(int x,int y){    next0[++cnt0]=head0[x];    head0[x]=cnt0;    list0[cnt0]=y;}inline void build(){    for (int i=1;i<=r;i++)        for (int j=0;j<a[i].size();j++)            if (opt[a[i][j]]==1)             {                for (int k=0;k<a[i].size();k++)                {                    if (k==j) continue;                    insert(a[i][j],a[i][k]);                    if (opt[a[i][k]]==1) insert(a[i][k],a[i][j]);                }                break;            }    for (int i=1;i<=c;i++)        for (int j=0;j<b[i].size();j++)            if (opt[b[i][j]]==2)            {                for (int k=0;k<b[i].size();k++)                {                    if (k==j) continue;                    insert(b[i][j],b[i][k]);                    if (opt[b[i][k]]==2) insert(b[i][k],b[i][j]);                }                break;            }    for (int i=1;i<=n;i++)        if (opt[i]==3)            for (int j=0;j<8;j++)            {                int xx=x[i]+dx[j],yy=y[i]+dy[j];                if (mp[xx][yy]) insert(i,mp[xx][yy]);            }}void dfs(int x){    dfn[x]=low[x]=++tot;    inset[x]=1;    stack[++top]=x;    for (int i=head[x];i;i=next[i])        if (!dfn[list[i]])        {            dfs(list[i]);            low[x]=min(low[x],low[list[i]]);        }        else if (inset[list[i]]) low[x]=min(low[x],dfn[list[i]]);    if (low[x]==dfn[x])    {        int i=-1; scc++;        while (i!=x)        {            i=stack[top--];            inset[i]=0;            belong[i]=scc;            num[scc]++;        }    }}inline void tarjan(){    for (int i=1;i<=n;i++) if (!dfn[i]) dfs(i);}inline void rebuild(){    for (int i=1;i<=n;i++)        for (int j=head[i];j;j=next[j])            if (belong[i]!=belong[list[j]])                insert0(belong[i],belong[list[j]]);}void dp(int x){    v[x]=1;    for (int i=head0[x];i;i=next0[i])    {        if (!v[list0[i]]) dp(list0[i]);        deep[x]=max(deep[x],deep[list0[i]]);    }    deep[x]+=num[x];    ans=max(ans,deep[x]);}int main(){    n=read(); r=read(); c=read();    for (int i=1;i<=n;i++)    {        x[i]=read(),y[i]=read(),opt[i]=read();        mp[x[i]][y[i]]=i;        a[x[i]].push_back(i);        b[y[i]].push_back(i);    }    build();    tarjan();    rebuild();    for (int i=1;i<=scc;i++)        if (!v[i]) dp(i);    cout << ans;    return 0;}
0 0
原创粉丝点击