题目链接:P3387 【模板】缩点

缩点板子,所谓\(dp\)就是拓扑排序(毕竟可以重走边),像\(SPFA\)一样松弛就好,就是重边极其烦人,还加了排序(绝对自己想的,然鹅拓扑的思路不是)。

下面上代码:

(为了突出惨烈性,我把调试语句留了下来......)

\(Code\):

#include<iostream>
#include<cstdio>
#include<cstring>
#include<stack>
#include<queue>
#include<algorithm>
using namespace std;
const int MAXN=1e5+5;
struct node
{
int to,nxt;
}e[MAXN],g[MAXN];
int heade[MAXN],cnte=0;
int headg[MAXN],cntg=0;
void adde(int u,int v)
{
e[++cnte].to=v;
e[cnte].nxt=heade[u];
heade[u]=cnte;
}
void addg(int ux,int vx)
{
g[++cntg].to=vx;
g[cntg].nxt=headg[ux];
headg[ux]=cntg;
}
int low[MAXN],num[MAXN],belong[MAXN],vis[MAXN];
int c=0,val[MAXN];
stack<int> s;
queue<int> q;
int indexx=0;
int n,m,l,r,w[MAXN];
void dfs1(int cur,int fa)
{
low[cur]=++indexx;
num[cur]=indexx;
s.push(cur);
vis[cur]=1;
for(int i=heade[cur];i;i=e[i].nxt)
{
int j=e[i].to;
if(!low[j]) dfs1(j,cur),low[cur]=min(low[cur],low[j]);
else if(vis[j])low[cur]=min(low[cur],num[j]);
}
if(low[cur]==num[cur])
{
int k;
c+=1;
do
{
k=s.top();
s.pop();
vis[k]=0;
belong[k]=c;
val[c]+=w[k];
}while(cur!=k);
}
}
int b[MAXN],maxn=0,deg[MAXN],dis[MAXN]={0};
struct gg
{
int uu,vv;
}dl[MAXN];
int cuv=0;
bool cmp(gg n,gg m)
{
if(n.uu^m.uu) return n.uu<m.uu;
else return n.vv<m.vv;
}
int main()
{
scanf("%d%d",&n,&m);
for(int i=1;i<=n;i++) scanf("%d",&w[i]);
for(int i=1;i<=m;i++) scanf("%d%d",&l,&r),adde(l,r);
for(int i=1;i<=n;i++) if(!low[i]) dfs1(i,i);
/*for(int i=1;i<=n;i++) cout<<belong[i]<<" ";
cout<<endl;
for(int i=1;i<=c;i++) cout<<val[i]<<" ";
cout<<endl;*/
for(int i=1;i<=n;i++)
{
for(int x=heade[i];x;x=e[x].nxt)
{
int j=e[x].to;
int k=belong[i];
int t=belong[j];
if(t^k) dl[++cuv].uu=k,dl[cuv].vv=t;
//addg(k,t),deg[t]++,cout<<k<<" "<<t<<"\n";
}
}
//cout<<endl;
sort(dl+1,dl+cuv+1,cmp);
int lu=-1,lv=-1;
for(int i=1;i<=cuv;i++)
{
if((dl[i].uu!=lu)||(dl[i].vv!=lv))
{
//cout<<dl[i].uu<<" "<<dl[i].vv<<"\n";
addg(dl[i].uu,dl[i].vv);
lu=dl[i].uu,lv=dl[i].vv;
deg[dl[i].vv]++;
}
else continue;
}
/*for(int i=1;i<=c;i++) cout<<deg[i]<<" ";
cout<<endl;
for(int i=1;i<=c;i++)
{
for(int j=headg[i];j;j=g[j].nxt) cout<<g[j].to<<" ";
cout<<"\n";
}*/
for(int i=1;i<=c;i++)
{
if(!deg[i]) q.push(i);
}
for(int i=1;i<=c;i++) dis[i]=val[i];
while(!q.empty())
{
int now=q.front();
q.pop();
//cout<<now<<" ";
for(int i=headg[now];i;i=g[i].nxt)
{
int j=g[i].to;
deg[j]--;
dis[j]=max(dis[j],dis[now]+val[j]);
if(!deg[j]) q.push(j);
}
}
//cout<<endl;
for(int i=1;i<=c;i++) maxn=max(maxn,dis[i]);
//for(int i=1;i<=c;i++)cout<<dis[i]<<" ";
printf("%d\n",maxn);
return 0;
}

其实除了码量还挺朴素的......

解题报告+板子:luogu P3387 【模板】缩点的更多相关文章

  1. 解题报告:luogu P1115(模板 最大子段和)

    题目链接:P1115 最大子段和 告诉你,这个我调了一天的题是橙题...... 线性容易得到,放篇题解: #include<bits/stdc++.h> using namespace s ...

  2. 【Luogu P3387】缩点模板(强连通分量Tarjan&拓扑排序)

    Luogu P3387 强连通分量的定义如下: 有向图强连通分量:在有向图G中,如果两个顶点vi,vj间(vi>vj)有一条从vi到vj的有向路径,同时还有一条从vj到vi的有向路径,则称两个顶 ...

  3. 模板+解题报告:luogu P3385 【模板】负环

    题目链接:P3385 [模板]负环 缩点板子. 看日报上说\(DFS\)会炸(我确实打炸了),就根据他的说明\(yy\)了\(BFS\),多一个记录步数的数组即可(我用的\(len[]\)),若\(l ...

  4. 解题报告:luogu P1433 吃奶酪

    题目链接:P1433 吃奶酪 我感觉可以改成:[模板]TSP问题(商旅问题) 了. 爆搜\(T\)一个点,考虑状压\(dp\)(还是爆搜). 我们用\(dp[i][j]\)表示现在是\(i\)状态,站 ...

  5. 解题报告:luogu P2299

    题目链接:P2299 Mzc和体委的争夺战 单源最短路板子题吗,体面晦涩难懂(语文不好),以为是有向图,只有\(30pts\),其实是无向的,我使用了刚学来的\(SPFA\),通过了此题: \(Cod ...

  6. 解题报告:luogu P2220

    指挥使走后一脸懵逼,然后想起了一道水\(SB\)的省选题. 这是毒瘤乘法分配率的应用,似乎还有一篇,算是入门题. 对了,这题连接:P2220 [HAOI2012]容易题 然而蒟蒻还是先自闭了一会... ...

  7. 解题报告:luogu P1196 [NOI2002]银河英雄传说

    由于并查集让我很自闭(其实是我太弱了),所以学习了加权并查集,这是例题: 题目链接:P1196 [NOI2002]银河英雄传说 不是很简单,但对于大佬还是签到题. 合并与路径压缩时直接维护\(dis[ ...

  8. 解题报告:luogu P5543 [USACO19FEB]The Great Revegetation S

    题目链接:P5543 [USACO19FEB]The Great Revegetation S 好坑啊,都身败名裂了. 思路一: 考虑染色法,跑一遍搜所就好了,不给代码了. 思路二: 考虑并查集,我想 ...

  9. 解题报告:luogu P5745 【深基附B例】数列求和

    题目链接:P5745 [深基附B例]数列求和 现在想说:\(O(N)\)的题要不怎么也想不出来,要不灵光乍现,就像这道题. 我们维护一个类似单调队列的加法单调队列: 若相加大于此数,就将队尾元素弹出, ...

随机推荐

  1. UCS内存问题排查

    UCS使用双列直插式内存模块(Dual In-line Memory Module (DIMM) )作为RAM模块. 根据文档介绍,主要有如下部分:1.Memory placement <内存放 ...

  2. Java面向对象编程 -3.3

    综合实战 简单Java类 在以后进行项目开发与设计的过程之中,简单Java类都将作为一个重要的组成部分存在,慢慢接触到正规的项目设计后, 简单Java类无处不再,并且有可能产生一系列的变化. 所谓的简 ...

  3. ES查询不重复的数据

    GET ana-apk/_search #查询不重复的mac地址{  "size": 10,  "aggs": {    "MAC": {  ...

  4. leetCode练题——26. Remove Duplicates from Sorted Array

    1.题目 26. Remove Duplicates from Sorted Array--Easy Given a sorted array nums, remove the duplicates  ...

  5. DOM的一些小总结

    HTML DOM的结构:可以把HTML看成一个个的节点. 节点: HTML DOM对象 --  方法和属性 一些DOM 对象方法 nodeName 属性 nodeValue 属性 nodeType:节 ...

  6. spark实验(一)--spark安装(1)

    一.实验目的 (1)掌握 Linux 虚拟机的安装方法.Spark 和 Hadoop 等大数据软件在 Linux 操作系统 上运行可以发挥最佳性能,因此,本教程中,Spark 都是在 Linux 系统 ...

  7. navicat12破解详细教程

    以管理员身份运行此注册机: 运行注册机 打开注册机后,1) Patch勾选Backup.Host和Navicat v12,然后点击Patch按钮: 默认勾选 找到Navicat Premium 12安 ...

  8. spring配置文件1

    applicationContext.xml: <?xml version="1.0" encoding="UTF-8"?><beans xm ...

  9. 数据库转换Mysql-Oracle之建表语句

    Mysql建库语句(导出的): DROP TABLE IF EXISTS `tablename`; CREATE TABLE `tablename` ( `C_DI_CDE` varchar(40) ...

  10. LeetCode 345. Reverse Vowels of a String(双指针)

    题意:给定一个字符串,反转字符串中的元音字母. 例如: Input: "leetcode" Output: "leotcede" 法一:双指针 class So ...