连通图 求至少有给几个点信息才能传遍全图,至少添加几条边才能使全图联通
第一个,染色后求入度为0的联通块。
第二个,染色后求入度为0的联通块和出度为0的联通块的最大值。//入度和出度是对联通块说的。
AC代码:
1 #include<iostream> 2 #include<string> 3 #include<iomanip> 4 #include<cstring> 5 #include<cmath> 6 #include<algorithm> 7 #include<stack> 8 #include<map> 9 #include<stdio.h> 10 #include<queue> 11 using namespace std; 12 # define maxn 200+10 13 # define inf 0x3f3f3f3f 14 # define ll long long 15 int num,n,ans; 16 int dfn[maxn]; 17 int low[maxn]; 18 int in[maxn]; 19 int out[maxn]; 20 int color[maxn]; 21 int col; 22 int vis[maxn]; 23 int Map[maxn][maxn]; 24 map<int,int> 25 stack<int>q; 26 vector<int>wakaka[maxn]; 27 void tarjan(int u) 28 { 29 q.push(u); 30 vis[u]=1; 31 low[u]=dfn[u]=++num; 32 int len=wakaka[u].size(); 33 for(int i=0; i<len; i++) 34 { 35 int v=wakaka[u][i]; 36 if(vis[v]==0) 37 { 38 tarjan(v); 39 low[u]=min(low[u],low[v]); 40 } 41 else if(vis[v ]==1) 42 low[u]=min(low[u],dfn[v]); 43 } 44 if(low[u]==dfn[u]) 45 { 46 int t; 47 col++; 48 do 49 { 50 t=q.top(); 51 q.pop(); 52 vis[t]=-1; 53 color[t]=col; 54 } 55 while(u!=t); 56 } 57 } 58 int main() 59 { 60 memset(vis,0,sizeof(vis)); 61 memset(color,0,sizeof(color)); 62 memset(dfn,0,sizeof(dfn)); 63 memset(low,0,sizeof(low)); 64 memset(in,0,sizeof(in)); 65 memset(out,0,sizeof(out)); 66 num=col=0; 67 int temp,ed; 68 scanf("%d",&n); 69 for(int i=1; i<=n; i++) 70 { 71 while(~scanf("%d",&temp)&&temp) 72 { 73 wakaka[i].push_back(temp); 74 } 75 } 76 for(int i=1; i<=n; i++) 77 { 78 if(vis[i]==0) 79 { 80 tarjan(i); 81 } 82 } 83 if(col==1)printf("%d\n%d\n",1,0); 84 else 85 { 86 int t1=0,t2=0; 87 for(int i=1; i<=n; i++) 88 { 89 int t=color[i]; 90 int flag=0; 91 int len=wakaka[i].size(); 92 for(int j=0; j<len; j++) 93 { 94 int temp=wakaka[i][j]; 95 if(color[temp]!=t) 96 { 97 in[color[temp]]++; 98 out[t]++; 99 } 100 } 101 } 102 for(int i=1; i<=col; i++) 103 { 104 if(in[i]==0)t1++; 105 if(out[i]==0)t2++; 106 } 107 printf("%d\n%d\n",t1,max(t1,t2)); 108 } 109 return 0; 110 111 } 112