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

本文介绍了一种解决复杂图论问题的方法,通过构建特定的数据结构来表达节点间的关系,并运用深度优先搜索进行强连通分量分析。此外,还实现了基于此结构的动态规划算法以找出最长路径。

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


#include<iostream>
#include<cstdio>
#include<vector>
#include<map>
#define N 1000005
using 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;
}


源码地址: https://pan.quark.cn/s/d1f41682e390 miyoubiAuto 米游社每日米游币自动化Python脚本(务必使用Python3) 8更新:更换cookie的获取地址 注意:禁止在B站、贴吧、或各大论坛大肆传播! 作者已退游,项目不维护了。 如果有能力的可以pr修复。 小引一波 推荐关注几个非常可爱有趣的女孩! 欢迎B站搜索: @嘉然今天吃什么 @向晚大魔 @乃琳Queen @贝拉kira 第三方库 食用方法 下载源码 在Global.py中设置米游社Cookie 运行myb.py 本地第一次运行时会自动生产一个文件储存cookie,请勿删除 当前仅支持单个账号! 获取Cookie方法 浏览器无痕模式打开 http://user.mihoyo.com/ ,登录账号 按,打开,找到并击 按刷新页面,按下图复制 Cookie: How to get mys cookie 当触发时,可尝试按关闭,然后再次刷新页面,最后复制 Cookie。 也可以使用另一种方法: 复制代码 浏览器无痕模式打开 http://user.mihoyo.com/ ,登录账号 按,打开,找到并击 控制台粘贴代码并运行,获得类似的输出信息 部分即为所需复制的 Cookie,击确定复制 部署方法--腾讯云函数版(推荐! ) 下载项目源码和压包 进入项目文件夹打开命令行执行以下命令 xxxxxxx为通过上面方式或取得米游社cookie 一定要用双引号包裹!! 例如: png 复制返回内容(包括括号) 例如: QQ截图20210505031552.png 登录腾讯云函数官网 选择函数服务-新建-自定义创建 函数名称随意-地区随意-运行环境Python3....
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值