poj1236 Network of Schools (tarjan缩点+求入度为0的点和出度为0的点的个数)
来源:互联网 发布:淘宝店铺层级划分 编辑:程序博客网 时间:2024/06/07 10:28
题目大意:N(2<N<100)各学校之间有单向的网络,每个学校得到一套软件后,可以通过单向网络向周边的学校传输
问题1:初始至少需要向多少个学校发放软件,使得网络内所有的学校最终都能得到软件。
问题2:至少需要添加几条传输线路(边),使任意向一个学校发放软件后,经过若干次传送,网络内所有的学校最终都能得到软件。
强连通分量缩点求入度为0的个数和出度为0的分量个数
去掉题目背景就变成了:
给你一个有向图(顶点数<=100),
你需要:
1、至少选几个顶点,使从这些顶点出发能到达所有的点
2、至少加几条边,使从任意一个顶点出发能到达所有的点
解题思路:
1、缩点,形成DAG
2、求出在DAG上,有多少个顶点入度为0(ans1),有多少个顶点出度为0(ans2)
所以,
第一问就变成了:DAG中有几个入度为0的点
第二问要求形成有向图的强连通图,那么第二问就变成了:对于一个DAG,至少加几条边使它变成强连通图(有向)
易知:对于有向图的强连通图中的每一个顶点一定有它的入度和出度都不为0
假设DAG中我们有n个入度为0的点,m个出度为0的点,
为了让每一个点入度都不为0,我们把这n个点每一个点都连入一条边;
为了让每一个点出度都不为0,我们把这m个点每一个点都连出一条边;
同时,要求加边最少
显然,我们只需要从出度为0的点连出一条边同时把它连入入度为0的点,形成一一对应,即最优选择
情况如下:
1、m=n 我们只需要连接m条边即可
2、m>n 按照上面的最优选择,我们加了n条边,还剩下(m-n)个出度为0的点,对于这些点我们每一个都连出一条边,所以一共有m条边
3、m<n 按照上面的最优选择,我们加了m条边,还剩下(n-m)个入度为0的点,对于这些点我们每一个都连入一条边,所以一共有n条边
综上所述:对于一个DAG,至少加 max(n,m)几条边使它变成强连通图(有向)
显然,第一问的答案为ans1,第二问的答案为max(ans1,ans2)
注意:对于一个本身就是强连通图的,显然第一问答案是1,第二问答案是0。
但是由于缩点后形成单独的一个点,所以第二问会输出1,要特判出这种情况
var n,l,ans1,ans2,x :longint; i :longint; t,p,q :longint; last :array[0..110] of longint; ru,chu :array[0..210] of longint; pre,other :array[0..10010] of longint; top,time :longint; dfn,low,belong,z:array[0..110] of longint; flag :array[0..110] of boolean;function max(a,b:longint):longint;begin if a>b then exit(a) else exit(b);end;function min(a,b:longint):longint;begin if a<b then exit(a) else exit(b);end;procedure dfs(x:longint);var p,q,cur:longint;begin inc(time); dfn[x]:=time; low[x]:=time; inc(top); z[top]:=x; flag[x]:=true; // q:=last[x]; while (q<>0) do begin p:=other[q]; if dfn[p]=0 then begin dfs(p); low[x]:=min(low[x],low[p]); end else if flag[p] then low[x]:=min(low[x],dfn[p]); q:=pre[q]; end; // if dfn[x]=low[x] then begin cur:=-1;inc(t); while (cur<>x) do begin cur:=z[top]; dec(top); belong[cur]:=n+t; flag[cur]:=false; end; end;end;procedure connect(x,y:longint);begin inc(l); pre[l]:=last[x]; last[x]:=l; other[l]:=y;end;begin read(n); l:=0;ans1:=0;ans2:=0;t:=0;time:=0;top:=0; for i:=1 to n do begin read(x); while (x<>0) do begin connect(i,x); read(x); end; end; // for i:=1 to n do if dfn[i]=0 then dfs(i); // for i:=1 to n do begin q:=last[i]; while (q<>0) do begin p:=other[q]; if (belong[p]<>belong[i]) then begin inc(chu[belong[i]]); inc(ru[belong[p]]); end; q:=pre[q]; end; end; // for i:=1 to t do begin if ru[n+i]=0 then inc(ans1); if chu[n+i]=0 then inc(ans2); end; // if (t=1) then begin writeln(1); writeln(0); end else begin writeln(ans1); writeln(max(ans1,ans2)); end;end.——by Eirlys
转载请注明出处=w=
- poj1236 Network of Schools (tarjan缩点+求入度为0的点和出度为0的点的个数)
- POJ1236-Network of Schools(Tarjan + 缩点)
- poj1236 Network of Schools(tarjan缩点)
- POJ 1236 Network of Schools(Tarjan Algorithm求强连通子集,缩点后DAG上出或入度为0的点)
- 【POJ1236】Network of Schools(Tarjan缩点)
- poj1236 Network of Schools(tarjan缩点)
- POJ 1236 Network of Schools 强联通分量求出度为0的点和入度为0的点的数目
- POJ 1236 Network of Schools(korasaju Algorithm求强连通子集,缩点后DAG上出或入度为0的点)
- POJ 1236--Network of Schools【scc缩点构图 && 求scc入度为0的个数 && 求最少加几条边使图变成强联通】
- poj1236 Network of Schools ,有向图求强连通分量(Tarjan算法),缩点
- [POJ1236]Network of Schools(Tarjan缩点+强连通分量)
- POJ1236---Network of Schools (强连通分量,缩点,Tarjan算法)
- 【强连通分量】Tarjan(缩点)POJ1236-Network of Schools
- POJ1236--Network of Schools(强连通+缩点)
- Network of Schools POJ1236(tarjan缩点+强连通分量模板)
- POJ1236 Network of Schools 强连通+缩点
- poj1236 Network of Schools(强连通-缩点)
- POJ1236 Network of Schools 强连通+缩点
- 制作一个简单的照片查看器(支持缩放手势)
- Android studio约束布局 ConstraintLayout
- Spring 初探(一)(Spring起步实例)
- leetcode--Isomorphic Strings
- 微信公众平台开发--方倍工作室[申明:来源于网络]
- poj1236 Network of Schools (tarjan缩点+求入度为0的点和出度为0的点的个数)
- 使用POI读取和写出EXCEL文件(写出部分待完善)
- Redis Shell命令行操作五种value数据类型
- 让Xcode 8支持iOS 7设备
- Some Examples of PCIE Transactions
- C语言程序
- ajax 讲解(入门级)
- Java核心技术点之反射
- 什么样的html结构是合理的?