poj 1236
来源:互联网 发布:桌面软件编程语言 编辑:程序博客网 时间:2024/06/05 07:40
poj 1236
强连通分量 tarjan。第一题,。。
题目:
传送
题目大意:有N个学校,从每个学校都能从一个单向网络到另外一个学校,两个问题
1:初始至少需要向多少个学校发放软件,使得网络内所有的学校最终都能得到软件。
2:至少需要添加几条边,使任意向一个学校发放软件后,经过若干次传送,网络内所有的学校最终都能得到软件。
解题思路:
求所有连通分量,然后缩点,构成一个有向无环的图,有多少个入度为0的点就是第一问的答案。
第二问呢,很神奇~
现在图上有n个入度为0的点,编号为0 1 2 .。。N,有m个出度为0的点。
把所有入度为0的点可达的出度0点,添加一条出边。需要n条边。
如果 n>m
那么就是n;否则再加m-n。一共是m
所一第二问是max{m,n}
代码:
zrtorz大神神神。
#include<cstdio>#include<cstring>#include<iostream>#include<algorithm>#include<cstdlib>using namespace std;int n,t,dfn[110],low[110],num,strong[110];int ru[110],chu[110];bool v[110];int stack[110],p;int next[10010],ver[10010],head[10010],tot;struct edge{int st,end;}a[10010];void add(int x,int y){ tot++; ver[tot]=y; next[tot]=head[x]; head[x]=tot;}void tarjan(int x){ int i; dfn[x]=low[x]=++num; stack[++p]=x;v[x]=1; for(i=head[x];i;i=next[i]) { if(!dfn[ver[i]]) { tarjan(ver[i]); low[x]=min(low[x],low[ver[i]]); } else if(v[ver[i]]) low[x]=min(low[x],low[ver[i]]); } if(low[x]==dfn[x]) { int y; ++t; do { y=stack[p--]; v[y]=0; strong[y]=t; } while(y!=x); }}int main(){ int i,j,k,ans1=0,ans2=0; cin>>n; for(i=1;i<=n;i++) while(scanf("%d",&j)!=EOF&&j!=0) add(i,j),a[tot].st=i,a[tot].end=j; for(i=1;i<=n;i++) { if(!dfn[i]) tarjan(i); } for(i=1;i<=tot;i++) { if(strong[a[i].st]==strong[a[i].end]) continue; chu[strong[a[i].st]]++; ru[strong[a[i].end]]++; } for(i=1;i<=t;i++) { if(!ru[i]) ans1++; } cout<<ans1<<endl; if(t==1) { cout<<0; return 0; } for(i=1;i<=t;i++) { if(!chu[i]) ans2++; } ans2=max(ans1,ans2); cout<<ans2; return 0;}
1 0
- POJ 1236
- poj 1236
- POJ 1236
- poj-1236
- poj 1236
- poj 1236
- poj 1236
- poj 1236
- poj 1236
- poj-1236
- 【POJ】1236
- poj-1236 强连通
- poj 1236
- POJ 1236 强联通
- POJ 1236 Tarjan算法
- POJ
- poj
- POJ
- A-挂饰|01背包
- Android AudioTrack
- 安卓开发小知识 - 3
- 虚拟机上安装CentOS7
- javascript getElementById 使用方法及用法
- poj 1236
- Delegate in UnrealEngine ——虚幻四中的委托
- 交换机开发(二)—— 三层交换机报文转发过程
- acm 算法竞赛 时间
- oil deposits——广搜
- 牛刀小试(一):垂直菜单
- 快速幂 快速乘法
- maven依赖包冲突问题
- Web工程目录和tomcat目录