标签:man art back push std esc sar ant and
Input
Output
Sample Input
5 2 4 3 0 4 5 0 0 0 1 0
Sample Output
1 2
给定一个图,问至少要选择多少个顶点,才能做到从这些顶点出发可以到达全部的顶点;至少要添加多少边才能使得从任意一个顶点出发可以到达全部顶点。
Tarjan求SCC,缩点建新图,第一问直接输出入度为0的点个数即可(因为新图是DAG),第二问输出max(in,out)即max(入度为0的点的个数,出度为0的点的个数)不会证明 放个链接https://blog.csdn.net/tomandjake_/article/details/81842963
注意特判cnt==1的情况。
#include <iostream> #include <cstdio> #include <cmath> #include <vector> using namespace std; const int N = 105; const int M = 10005; int ver[M],Next[M],head[N],dfn[N]={0},low[N]; int vc[M],nc[M],hc[N],tc=0; int sstack[N],ins[N],c[N]; vector<int>scc[N]; int n,m,tot=0,num=0,top=0,cnt=0; int deg_in[N]={0},deg_out[N]={0}; void add(int x, int y) { ver[++tot]=y,Next[tot]=head[x],head[x]=tot; } void add_c(int x,int y) { vc[++tc]=y,nc[tc]=hc[x],hc[x]=tc; } void tarjan(int x) { dfn[x]=low[x]=++num; sstack[++top]=x,ins[x]=1; int i; 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(ins[ver[i]]) low[x]=min(low[x],dfn[ver[i]]); } if(dfn[x]==low[x]) { cnt++; int y; do { y=sstack[top--],ins[y]=0; c[y]=cnt,scc[cnt].push_back(y); }while(x!=y); } } int main() { cin>>n; int i,j,x; for(i=1;i<=n;i++) { int x,y; while(scanf("%d",&y)&&y!=0) { x=i; add(x,y); } } for(i=1;i<=n;i++) { if(!dfn[i])tarjan(i); } int deg[N]={0}; for(x=1;x<=n;x++) { for(i=head[x];i;i=Next[i]) { int y=ver[i]; if(c[x]==c[y])continue; add_c(c[x],c[y]); deg_in[c[y]]++; deg_out[c[x]]++; } } int in=0,out=0; for(i=1;i<=cnt;i++)//注意 这里的新图一共有cnt个点 { if(deg_in[i]==0)in++; if(deg_out[i]==0)out++; } cout<<in<<endl; if(cnt!=1)cout<<max(in,out)<<endl; else cout<<0; return 0; }
POJ1236 Network of Schools(强连通分量)
标签:man art back push std esc sar ant and
原文地址:https://www.cnblogs.com/lipoicyclic/p/12821382.html