标签:class top iostream pop void 连通 强连通 include min
可以看出Tarjan缩点,但对于第一问,我竟然想到状压DP??
对于第二问,我想的是怎么添边成环??
对于第一问,统计入度为0的点即可
对于第二问,统计出度为0的点,与第一问取个max即可
因为要把所有点的入度出度都变成大于0的......
还有就是Tarjan缩点的写法,要用do while......
1 #include<iostream> 2 #include<cstdio> 3 #include<stack> 4 using namespace std; 5 const int maxn=107; 6 int dfn[maxn],low[maxn],head[maxn],cnt[maxn],color[maxn]; 7 int n,tot,num,count,top=1,sta[maxn]; 8 int in[maxn],out[maxn],map[maxn][maxn]; 9 bool ins[maxn]; 10 stack<int>s; 11 struct Edge{ 12 int next,to; 13 }edge[maxn*maxn]; 14 void addedge(int from,int to){ 15 edge[++num].next=head[from]; 16 edge[num].to=to; 17 head[from]=num; 18 } 19 void Tarjan(int u){ 20 dfn[u]=low[u]=++tot; 21 s.push(u);ins[u]=true; 22 for(int i=head[u];i;i=edge[i].next){ 23 int v=edge[i].to; 24 if(!dfn[v]){ 25 Tarjan(v); 26 low[u]=min(low[u],low[v]); 27 } 28 else if(ins[v]){ 29 low[u]=min(low[u],dfn[v]); 30 } 31 } 32 int k; 33 if(low[u]==dfn[u]){ 34 count++; 35 do{ 36 k=s.top();s.pop(); 37 color[k]=count; 38 ins[k]=false; 39 }while(k!=u); 40 41 } 42 } 43 int main(){ 44 cin>>n; 45 for(int i=1;i<=n;i++){ 46 int a;cin>>a; 47 while(a!=0){ 48 addedge(i,a); 49 cin>>a; 50 } 51 } 52 for(int i=1;i<=n;i++) 53 if(!dfn[i]) Tarjan(i); 54 for(int i=1;i<=n;i++){ 55 for(int j=head[i];j;j=edge[j].next){ 56 int v=edge[j].to; 57 if(color[i]!=color[v]){ 58 if(map[color[i]][color[v]]==0){ 59 in[color[v]]++;out[color[i]]++; 60 } 61 map[color[i]][color[v]]=1; 62 } 63 } 64 } 65 int ans1=0,ans2=0; 66 if(count==1) {cout<<1<<endl<<0<<endl;return 0;} 67 for(int i=1;i<=count;i++){ 68 if(in[i]==0) ans1++; 69 if(out[i]==0) ans2++; 70 } 71 ans2=max(ans1,ans2); 72 cout<<ans1<<endl<<ans2<<endl; 73 return 0; 74 }
记得要特判强连通分量就是本身的情况......
标签:class top iostream pop void 连通 强连通 include min
原文地址:https://www.cnblogs.com/lcan/p/9502053.html