Description

  一个有向图G=(V,E)称为半连通的(Semi-Connected),如果满足:?u,v∈V,满足u→v或v→u,即对于图中任意
两点u,v,存在一条u到v的有向路径或者从v到u的有向路径。若G'=(V',E')满足V'?V,E'是E中所有跟V'有关的边,
则称G'是G的一个导出子图。若G'是G的导出子图,且G'半连通,则称G'为G的半连通子图。若G'是G所有半连通子图
中包含节点数最多的,则称G'是G的最大半连通子图。给定一个有向图G,请求出G的最大半连通子图拥有的节点数K
,以及不同的最大半连通子图的数目C。由于C可能比较大,仅要求输出C对X的余数。

Input

  第一行包含两个整数N,M,X。N,M分别表示图G的点数与边数,X的意义如上文所述接下来M行,每行两个正整
数a, b,表示一条有向边(a, b)。图中的每个点将编号为1,2,3…N,保证输入中同一个(a,b)不会出现两次。N ≤1
00000, M ≤1000000;对于100%的数据, X ≤10^8

Output

  应包含两行,第一行包含一个整数K。第二行包含整数C Mod X.

Sample Input

6 6 20070603
1 2
2 1
1 3
2 4
5 6
6 4

Sample Output

3
3
——————————————————————————————————————————————
题目大意:
一个有向图,求图中的最大半连通子图的点数和方案数。
首先,对图进行缩点。因为环内的点肯定是连通的。
然后,图就变成了有向无环图,这样在上面进行拓扑排序。
最后,在拓扑序上进行DP。
只得了40分,后来看别的程序才发现问题,注意去重边。
——————————————————————————————————————————————

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 const int maxn=1e5+10,maxm=1e6+10;
 4 struct edge
 5 {
 6     int u,v,nxt;
 7 }e[maxm],ee[maxm];
 8 int head[maxn],js,headd[maxn],jss;
 9 void addage(edge e[],int head[],int &js,int u,int v)
10 {
11     e[++js].u=u;e[js].v=v;
12     e[js].nxt=head[u];head[u]=js;
13 }
14 int dfn[maxn],low[maxn],cnt,st[maxn],top,lt[maxn],lts,ltn[maxn];
15 void  tarjan(int u)
16 {
17     dfn[u]=low[u]=++cnt;
18     st[++top]=u;
19     for(int i=head[u];i;i=e[i].nxt)
20     {
21         int v=e[i].v;
22         if(!dfn[v])
23         {
24             tarjan(v);
25             low[u]=min(low[u],low[v]);
26         }
27         else if(!lt[v])
28             low[u]=min(low[u],dfn[v]);
29     }
30     if(dfn[u]==low[u])
31     {
32         lt[u]=++lts;ltn[lts]++;
33         while(st[top]!=u)lt[st[top--]]=lts,ltn[lts]++;
34         --top;
35     }
36 }
37 int n,m,x;
38 int f[maxn],ff[maxn];
39 int cd[maxn],rd[maxn];
40 int maxd,maxf;
41 int pc[maxn];
42 queue<int>q;
43 void dfs()
44 {
45     while(!q.empty())
46     {
47         int u=q.front();q.pop();
48         maxd=max(maxd,f[u]);
49         for(int i=headd[u];i;i=ee[i].nxt)
50         {
51             int v=ee[i].v;
52             rd[v]--;
53             if(rd[v]==0)q.push(v);
54             if(pc[v]==u)continue;
55             if(f[u]+ltn[v]>f[v])
56             {
57                 f[v]=f[u]+ltn[v];
58                 ff[v]=ff[u];
59
60             }
61             else if(f[u]+ltn[v]==f[v])
62             {
63                 ff[v]=(ff[u]+ff[v])%x;
64             }
65             pc[v]=u;
66         }
67     }
68 }
69 int main()
70 {
71     scanf("%d%d%d",&n,&m,&x);
72     for(int u,v,i=1;i<=m;++i)
73     {
74         scanf("%d%d",&u,&v);
75         addage(e,head,js,u,v);
76     }
77     for(int i=1;i<=n;++i)
78         if(!dfn[i])tarjan(i);
79     for(int u=1;u<=n;++u)
80         for(int i=head[u];i;i=e[i].nxt)
81             if(lt[e[i].u]!=lt[e[i].v])addage(ee,headd,jss,lt[e[i].u],lt[e[i].v]),cd[lt[e[i].u]]++,rd[lt[e[i].v]]++;
82     for(int i=1;i<=lts;++i)
83         if(rd[i]==0)q.push(i),f[i]=ltn[i],ff[i]=1;
84     dfs();
85     for(int i=1;i<=lts;++i)
86     {
87         if(f[i]==maxd)maxf=(maxf+ff[i])%x;
88     }
89     printf("%d\n%d\n",maxd,maxf);
90     return 0;
91 }

View Code

转载于:https://www.cnblogs.com/gryzy/p/10736239.html

LOJ10092半连通子图相关推荐

  1. 解题报告:luogu P2272 [ZJOI2007]最大半连通子图(tarjan缩点、递推DP、hash、set判重)

    这时yxc上课时讲解的截图. 一般用到tarjan算法的题目步骤都非常相似: tarjan算法 缩点,建图(这里要判重) 按照拓扑序递推(这里缩点以后逆向就已经是拓扑序了)/ 循环遍历新图求解答案. ...

  2. BZOJ 1093 [ZJOI2007]最大半连通子图

    1093: [ZJOI2007]最大半连通子图 Description 一个有向图G=(V,E)称为半连通的(Semi-Connected),如果满足:?u,v∈V,满足u→v或v→u,即对于图中任意 ...

  3. tyvj——P3524 最大半连通子图

    P3524 最大半连通子图 时间: 3000ms / 空间: 165536KiB / Java类名: Main 描述 输入格式 第一行包含两个整数N,M,X.N,M分别表示图G的点数与边数,X的意义如 ...

  4. BZOJ 1093 ZJOI 2007 最大半连通子图 强联通分量+拓扑图DP

    今天是放假的第一天(不说什么废话了) 什么是半连通子图?就是此图中包含的所有点两两点之间至少有一条单向路径. 题目问了两个问题 1.最大半连通子图的大小 2.最大半连通子图的个数 好了,这个问题看上去 ...

  5. P2272-[ZJOI2007]最大半连通子图【tarjan,缩点】

    正题 题目链接:https://www.luogu.com.cn/problem/P2272 题目大意 半连通图定义为任意两个点(u,v)(u,v)(u,v)满足uuu可以到vvv或vvv可以到uuu ...

  6. java 无向图子图_无向图的连通子图

    /* * CC.h * * Created on: 2014年6月3日 * Author: zhongchao * 计算无向图中的连通分量 */ #ifndef _CC_ #define _CC_ # ...

  7. 数据结构——图:极大小连通子图、图的存储结构、图的遍历

    图的基本概念: 极大连通子图就是连通分量. 极大连通子图与连通分量在无向图(undirected graph)这个前提下是等同的概念. 极小连通子图: 减去任何一条边就不再连通. 不管树还是二叉树:n ...

  8. 获得无向图连通子图_讲透学烂二叉树(一):图的概念和定义—各种属性特征浅析...

    树和图的概念 图是一种特殊的数据结构,由点和边构成,它可以用来描述元素之间的网状关系,这个网状没有顺序,也没有层次,就是简单的把各个元素连接起来. 图的概念和基本性质 图(graph):图(graph ...

  9. Python 计算两个连通子图距离_复杂网络分析之python利器NetworkX

    点击蓝字 关注我们 1 networkx介绍 networkx在2002年5月产生,是一个用Python语言开发的图论与复杂网络建模工具,内置了常用的图与复杂网络分析算法,可以方便的进行复杂网络数据分 ...

  10. 怎样获得网络的最大连通子图

    要获得网络的最大连通子图,你可以使用称为 "Kosaraju 算法" 的算法.它的基本思想是: 使用深度优先搜索算法求出图中的所有强连通分量. 将图的所有边反向,再求出所有的强连通 ...

最新文章

  1. python语言基础-详细的总结一下python入门基础语言知识!
  2. 美国国防部黑客大比武 “白帽黑客”受邀请
  3. python中的@符号的作用
  4. Parity Alternated Deletions
  5. MSF(四):常用弱点扫描模块
  6. Intellij关闭自动更新
  7. Dungeon Master(三维bfs)
  8. mysql设置自动递增_《MySQL数据库》约束条件和自增长序列
  9. 漫画:什么是冒泡排序
  10. 160 - 15 blaster99.exe
  11. Linux的压缩相关命令(转载)
  12. 干货 | 深度文本分类综述(12篇经典论文)
  13. jmeter压力测试指标解释
  14. 王朝娱乐H5 游戏源码(cocos creator , pomelo + mongDB)搭建教程
  15. OpenCV 实现读取摄像头、视频读取保存 (C++)
  16. C++语言风格流变史(转)
  17. linux wifi 8192移植 及部分wifi工具的使用
  18. Automader 使用教程 - 01 你好,左右抽
  19. 贝塞尔曲线想到的--真的很美,但是有时很丑
  20. pygame-KidsCanCode系列jumpy-part17-mask-collide碰撞检测

热门文章

  1. 【渝粤教育】电大中专中药制剂学作业 题库
  2. 基于矩阵分解的隐因子模型
  3. 【Python3 爬虫】12_代理IP的使用
  4. 使用docker部署.net core应用
  5. python序列化-复习
  6. [转]Fedora Core Linux 9 中安装VMware Tools-6.5.0
  7. 云计算openstack核心组件——nova计算服务(7)
  8. redis系列(三):python操作redis
  9. WebGL多模型光照综合实例
  10. framework7日期插件使用