最大半联通子图对应缩点后的$DAG$上的最长链

复杂度$O(n + m)$

  1. #include <cstdio>
  2. #include <cstring>
  3. #include <iostream>
  4. using namespace std;
  5.  
  6. extern inline char gc() {
  7. static char RR[], *S = RR + , *T = RR + ;
  8. if(S == T) fread(RR, , , stdin), S = RR;
  9. return *S ++;
  10. }
  11. inline int read() {
  12. int p = , w = ; char c = gc();
  13. while(c > '' || c < '') { if(c == '-') w = -; c = gc(); }
  14. while(c >= '' && c <= '') p = p * + c - '', c = gc();
  15. return p * w;
  16. }
  17.  
  18. #define ri register int
  19. #define sid 1005000
  20.  
  21. int n, m, id, nid, cnp, mod, top;
  22. int pre[sid], nxt[sid], node[sid], cap[sid], vis[sid];
  23. int low[sid], dfn[sid], st[sid], ins[sid], cnt[sid], b[sid], deg[sid], q[sid];
  24.  
  25. inline void addedge(int u, int v) {
  26. nxt[++ cnp] = cap[u]; cap[u] = cnp;
  27. pre[cnp] = u; node[cnp] = v; deg[v] ++;
  28. }
  29.  
  30. void tarjan(int o, int fa) {
  31. low[o] = dfn[o] = ++ id; st[++ top] = o; ins[o] = ;
  32. #define cur node[i]
  33. for(int i = cap[o]; i; i = nxt[i]) {
  34. if(!dfn[cur]) tarjan(cur, o), low[o] = min(low[o], low[cur]);
  35. else if(ins[cur]) low[o] = min(low[o], dfn[cur]);
  36. }
  37. if(dfn[o] == low[o]) {
  38. int p; ++ nid;
  39. do{ p = st[top --]; b[p] = nid;
  40. ins[p] = ; cnt[nid] ++;
  41. } while(p != o);
  42. }
  43. }
  44.  
  45. inline void inc(int &a, int b)
  46. { a += b; if(a >= mod) a -= mod; }
  47.  
  48. struct dp {
  49. int sz, num;
  50. friend void cmax(dp &a, dp b) {
  51. if(b.sz > a.sz) a = b;
  52. else if(b.sz == a.sz) inc(a.num, b.num);
  53. }
  54. } f[sid];
  55.  
  56. void top_dp() {
  57. int fr = , to = ;
  58. for(ri i = ; i <= nid; i ++) {
  59. if(!deg[i]) q[++ to] = i;
  60. f[i] = { cnt[i], };
  61. }
  62. #define cur node[i]
  63. while(fr <= to) {
  64. int o = q[fr ++];
  65. for(ri i = cap[o]; i; i = nxt[i]) {
  66. deg[cur] --; if(!deg[cur]) q[++ to] = cur;
  67. if(vis[cur] == o) continue;
  68. cmax(f[cur], (dp){ f[o].sz + cnt[cur], f[o].num } );
  69. vis[cur] = o;
  70. }
  71. }
  72. dp ans = { , };
  73. for(ri i = ; i <= nid; i ++) cmax(ans, f[i]);
  74. printf("%d\n%d\n", ans.sz, ans.num);
  75. }
  76.  
  77. int main() {
  78. n = read(); m = read(); mod = read();
  79. for(ri i = ; i <= m; i ++) {
  80. int u = read(), v = read();
  81. addedge(u, v);
  82. }
  83. for(ri i = ; i <= n; i ++)
  84. if(!dfn[i]) tarjan(i, );
  85. memset(cap, , (n + ) << );
  86. memset(deg, , (n + ) << );
  87. int cno = cnp; cnp = ;
  88. for(ri i = ; i <= cno; i ++)
  89. if(b[pre[i]] != b[node[i]]) addedge(b[pre[i]], b[node[i]]);
  90. top_dp();
  91. return ;
  92. }

bzoj1093 [ZJOI2007]最大半联通子图 缩点 + 拓扑序的更多相关文章

  1. bzoj1093[ZJOI2007]最大半连通子图(tarjan+拓扑排序+dp)

    Description 一个有向图G=(V,E)称为半连通的(Semi-Connected),如果满足:?u,v∈V,满足u→v或v→u,即对于图中任意两点u,v,存在一条u到v的有向路径或者从v到u ...

  2. bzoj 1093 [ZJOI2007]最大半连通子图——缩点+拓扑

    题目:https://www.lydsy.com/JudgeOnline/problem.php?id=1093 缩点+拓扑,更新长度的时候维护方案数. 结果没想到处理缩点后的重边,这样的话方案数会算 ...

  3. 【BZOJ】1093: [ZJOI2007]最大半连通子图(tarjan+拓扑序)

    http://www.lydsy.com/JudgeOnline/problem.php?id=1093 两个条件综合起来加上求最大的节点数,那么很明显如果是环一定要缩点. 然后再仔细思考下就是求da ...

  4. 【BZOJ1093】[ZJOI2007]最大半联通子图(Tarjan,动态规划)

    [BZOJ1093][ZJOI2007]最大半联通子图(Tarjan,动态规划) 题面 BZOJ 洛谷 洛谷的讨论里面有一个好看得多的题面 题解 显然强连通分量对于题目是没有任何影响的,直接缩点就好了 ...

  5. [bzoj 1093][ZJOI2007]最大半联通子图(强联通缩点+DP)

    题目:http://www.lydsy.com:808/JudgeOnline/problem.php?id=1093 分析: 首先肯定是先把强联通全部缩成一个点,然后成了一个DAG 下面要知道一点: ...

  6. BZOJ1093 [ZJOI2007]最大半连通子图 【tarjan缩点 + DAG最长路计数】

    题目 一个有向图G=(V,E)称为半连通的(Semi-Connected),如果满足:?u,v∈V,满足u→v或v→u,即对于图中任意 两点u,v,存在一条u到v的有向路径或者从v到u的有向路径.若G ...

  7. bzoj1093: [ZJOI2007]最大半连通子图 scc缩点+dag上dp

    一个有向图G=(V,E)称为半连通的(Semi-Connected),如果满足:?u,v∈V,满足u→v或v→u,即对于图中任意两点u,v,存在一条u到v的有向路径或者从v到u的有向路径.若G'=(V ...

  8. BZOJ1093 [ZJOI2007]最大半连通子图

    Description 一个有向图G=(V,E)称为半连通的(Semi-Connected),如果满足:?u,v∈V,满足u→v或v→u,即对于图中任意两点u,v,存在一条u到v的有向路径或者从v到u ...

  9. BZOJ1093: [ZJOI2007]最大半连通子图(tarjan dp)

    题意 一个有向图G=(V,E)称为半连通的(Semi-Connected),如果满足:?u,v∈V,满足u→v或v→u,即对于图中任意两点u,v,存在一条u到v的有向路径或者从v到u的有向路径.若G' ...

随机推荐

  1. 【CodeForces】576 D. Flights for Regular Customers

    [题目]D. Flights for Regular Customers [题意]给定n个点m条边的有向图,每条边有di表示在经过该边前必须先经过di条边,边可重复经过,求1到n的最小经过边数.n,m ...

  2. 吐泡泡(2018年全国多校算法寒假训练营练习比赛(第二场)+栈模拟)+Plug-in(codeforces81A+栈模拟)

    吐泡泡题目链接:https://www.nowcoder.com/acm/contest/74/A 题目: 思路: 这种题目当初卡了我很久,今天早训时遇到一个一样得题,一眼就想到用栈模拟,就又回来把这 ...

  3. inviteflood 洪泛滥工具

    inviteflood是一种通过UDP/IP执行SIP/SDP INVITE消息泛洪的工具,描述可以参考:inviteflood Package Description 使用inviteflood工具 ...

  4. 郑轻校赛 2127 tmk射气球 (数学)

    Description 有一天TMK在做一个飞艇环游世界,突然他发现有一个气球匀速沿直线飘过,tmk想起了他飞艇上有一把弓,他打算拿弓去射气球,为了提高射击的准确性,他首先在飞艇上找到一个离气球最近的 ...

  5. 重载jquery on方法实现click事件在移动端的快速响应

    额,这个标题取的还真是挺装的... 其实我想表达的是jquery click事件如何在移动端自动转换成touchstart事件. 因为移动端click事件会比touchstart事件慢几拍 移动设备某 ...

  6. docker使用现有容器生成新的镜像

    /*运行docker run后 --则进入该容器里了 我们做一些变更,比如安装一些东西 ,然后针对这个容器进行创建新的镜像 */ 基本形式: docker commit -m "change ...

  7. 面试中关于Redis的问题看这篇就够了

    昨天写了一篇自己搭建redis集群并在自己项目中使用的文章,今天早上看别人写的面经发现redis在面试中还是比较常问的(笔主主Java方向).所以查阅官方文档以及他人造好的轮子,总结了一些redis面 ...

  8. perl6正则 1: ~~ , //, m//, rx//

    ~~ perl6 中, 要匹配一个正则, 使用 ~~ 智能匹配符. > so 'abcde' ~~ /a.c/ True > so 'abcde' ~~ /a.d/ False > ...

  9. Mysql储存过程5: while

    循环结构 while create procedure name() begin while 条件 do SQL语句 end while; end$ create procedure aa6() be ...

  10. 首次成功的web渗透

    web渗透 今天给大家讲一个最近做的一件令我振奋的一件事情 渗透培训刚刚结束的第二天 我在公网上挖到了我人生中的第一个站 总体来说个人真的很振奋人心      这个网站还没有进行更改但我已经通知了他们 ...