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
 
 
 
先用tarjan将强连通分量缩点,然后答案就是最长路,拓扑排序+dp就可,要求方案总数,只要在dp的时候搞一搞,记录方案数就好了。
我是参考hzwer大佬的,在此表示感谢。
 program semi(input,output);
type
etype=record
t,next:longint;
end;
var
e,c:array[..]of etype;
last,dfn,low,q,hav,belong,r,a,f,g,vis:array[..]of longint;
inq:array[..]of boolean;
n,m,p,i,j,u,v,cnt,tot,top,h,t,max,ans:longint;
procedure add(u,v:longint);
begin
inc(cnt);e[cnt].t:=v;e[cnt].next:=last[u];last[u]:=cnt;
end;
procedure tarjan(k:longint);
var
i:longint;
begin
inc(cnt);dfn[k]:=cnt;low[k]:=cnt;
inc(top);q[top]:=k;inq[k]:=true;
i:=last[k];
while i<> do
begin
if dfn[e[i].t]= then begin tarjan(e[i].t);if low[e[i].t]<low[k] then low[k]:=low[e[i].t]; end
else if inq[e[i].t] and (dfn[e[i].t]<low[k]) then low[k]:=dfn[e[i].t];
i:=e[i].next;
end;
if low[k]=dfn[k] then
begin
inc(tot);hav[tot]:=;
while q[top]<>k do begin inq[q[top]]:=false;belong[q[top]]:=tot;inc(hav[tot]);dec(top); end;
dec(top);inq[k]:=false;belong[k]:=tot;inc(hav[tot]);
end;
end;
procedure ins(u,v:longint);
begin
inc(cnt);c[cnt].t:=v;c[cnt].next:=a[u];a[u]:=cnt;inc(r[v]);
end;
begin
assign(input,'semi.in');assign(output,'semi.out');reset(input);rewrite(output);
readln(n,m,p);
cnt:=;fillchar(last,sizeof(last),);
for i:= to m do begin readln(u,v);add(u,v); end;
fillchar(dfn,sizeof(dfn),);tot:=;
for i:= to n do if dfn[i]= then begin cnt:=;top:=;tarjan(i); end;
cnt:=;fillchar(a,sizeof(a),);fillchar(r,sizeof(r),);
for i:= to n do
begin
j:=last[i];
while j<> do
begin
if belong[i]<>belong[e[j].t] then ins(belong[i],belong[e[j].t]);
j:=e[j].next;
end;
end;
h:=;t:=;
for i:= to tot do
begin
if r[i]= then begin inc(t);q[t]:=i; end;
f[i]:=hav[i];g[i]:=;
end;
fillchar(vis,sizeof(vis),);
while h<t do
begin
inc(h);i:=a[q[h]];
while i<> do
begin
dec(r[c[i].t]);if r[c[i].t]= then begin inc(t);q[t]:=c[i].t; end;
if vis[c[i].t]<>q[h] then
begin
if f[q[h]]+hav[c[i].t]>f[c[i].t] then begin f[c[i].t]:=f[q[h]]+hav[c[i].t];g[c[i].t]:=g[q[h]]; end
else if f[q[h]]+hav[c[i].t]=f[c[i].t] then g[c[i].t]:=(g[c[i].t]+g[q[h]]) mod p;
vis[c[i].t]:=q[h];
end;
i:=c[i].next;
end;
end;
max:=;
for i:= to tot do if f[i]>max then begin max:=f[i];ans:=g[i]; end else if f[i]=max then ans:=(ans+g[i]) mod p;
writeln(max);writeln(ans);
close(input);close(output);
end.

bzoj1093[ZJOI2007]最大半连通子图(tarjan+拓扑排序+dp)的更多相关文章

  1. 【bzoj1093】[ZJOI2007]最大半连通子图 Tarjan+拓扑排序+dp

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

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

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

  3. bzoj 1093 最大半连通子图 - Tarjan - 拓扑排序 - 动态规划

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

  4. BZOJ1093 ZJOI2007最大半连通子图(缩点+dp)

    发现所谓半连通子图就是缩点后的一条链之后就是个模板题了.注意缩点后的重边.写了1h+真是没什么救了. #include<iostream> #include<cstdio> # ...

  5. BZOJ 1093: [ZJOI2007]最大半连通子图( tarjan + dp )

    WA了好多次... 先tarjan缩点, 然后题意就是求DAG上的一条最长链. dp(u) = max{dp(v)} + totu, edge(u,v)存在. totu是scc(u)的结点数. 其实就 ...

  6. Luogu P2272 [ZJOI2007]最大半连通子图(Tarjan+dp)

    P2272 [ZJOI2007]最大半连通子图 题意 题目描述 一个有向图\(G=(V,E)\)称为半连通的\((Semi-Connected)\),如果满足:\(\forall u,v\in V\) ...

  7. 【tarjan 拓扑排序 dp】bzoj1093: [ZJOI2007]最大半连通子图

    思维难度不大,关键考代码实现能力.一些细节还是很妙的. Description 一个有向图G=(V,E)称为半连通的(Semi-Connected),如果满足:?u,v∈V,满足u→v或v→u,即对于 ...

  8. [luogu2272 ZJOI2007] 最大半连通子图 (tarjan缩点 拓扑排序 dp)

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

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

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

随机推荐

  1. 20155320 实验二 Java面向对象程序设计

    20155320 实验二 Java面向对象程序设计 实验内容 初步掌握单元测试和TDD 理解并掌握面向对象三要素:封装.继承.多态 初步掌握UML建模 熟悉S.O.L.I.D原则 了解设计模式 实验步 ...

  2. [POJ3041]Asteroids

    Asteroids 好久没打过网络流相关的题了...... 题意:一个矩阵n×n,有m个东西,一次去掉一整行或一整列,问最少次数. 题解:匈牙利. 把每行变成一个点(X集合),每列变成一个点(Y集合) ...

  3. Struts 2(八):文件上传

    第一节 基于Struts 2完成文件上传 Struts 2框架中没有提供文件上传,而是通过Common-FileUpload框架或COS框架来实现的,Struts 2在原有上传框架的基础上进行了进一步 ...

  4. 学习HTML 第三节.接近正题:HTML样式-CSS级联样式表

    CSS (Cascading Style Sheets)级联样式表 内联样式 内联样式- 在HTML元素中使用"style" 属性 使用内联样式的方法是在相关的标签中使用样式属性. ...

  5. Docker--从安装到搭建环境

    docker 1. ubuntu下安装docker 安装docker有两种方法: 一种是用官方的bash脚本一键安装. 直接一条命令就解决了: $ curl -sSL https://get.dock ...

  6. Phaser3让超级玛丽实现轻跳、高跳及加上对应的跳跃声音

      mario jumper 在线测试地址:http://www.ifiero.com/uploads/phaserjs3/jumper/ 空格键:轻按:跳低 ,长按:跳高键盘:--> 向右 , ...

  7. 用Python深入理解跳跃表原理及实现

    最近看 Redis 的实现原理,其中讲到 Redis 中的有序数据结构是通过跳跃表来进行实现的.第一次听说跳跃表的概念,感到比较新奇,所以查了不少资料.其中,网上有部分文章是按照如下方式描述跳跃表的: ...

  8. HTTP协议请求信息详解

    通常HTTP消息包括客户机向服务器的请求消息和服务器向客户机的响应消息.客户端向服务器发送一个请求,请求头包含请求的方法.URI.协议版本.以及包含请求修饰符.客户信息和内容的类似于MIME的消息结构 ...

  9. 会声会影2018提示dll文件丢失怎么办?

    一些会声会影2018用户,在安装.使用软件的过程中,会出现dll缺失的提示,导致软件无法打开,那么,出现这一问题要怎么解决.接下来小编为大家具体介绍下两种解决方法. 图1:dll丢失提示 打开会声会影 ...

  10. Hyperledger Fabric CouchDB as the State Database——使用CouchDB

    使用CouchDB作为状态数据库 状态数据库选项 状态数据库包括LevelDB和CouchDB.LevelDB是嵌入在peer进程中的默认键/值状态数据库,CouchDB是一个可选的外部状态数据库.与 ...