連通圖 求至少有給幾個點資訊才能傳遍全圖,至少新增幾條邊才能使全圖聯通
阿新 • • 發佈:2018-12-16
第一個,染色後求入度為0的聯通塊。
第二個,染色後求入度為0的聯通塊和出度為0的聯通塊的最大值。//入度和出度是對聯通塊說的。
AC程式碼:
#include<iostream> #include<string> #include<iomanip> #include<cstring> #include<cmath> #include<algorithm> #include<stack> #include<map> #include<stdio.h> #include<queue> using namespace std; # define maxn 200+10 # define inf 0x3f3f3f3f # define ll long long int num,n,ans; int dfn[maxn]; int low[maxn]; int in[maxn]; int out[maxn]; int color[maxn]; int col; int vis[maxn]; int Map[maxn][maxn]; map<int,int> stack<int>q; vector<int>wakaka[maxn]; void tarjan(int u) { q.push(u); vis[u]=1; low[u]=dfn[u]=++num; int len=wakaka[u].size(); for(int i=0; i<len; i++) { int v=wakaka[u][i]; if(vis[v]==0) { tarjan(v); low[u]=min(low[u],low[v]); } else if(vis[v ]==1) low[u]=min(low[u],dfn[v]); } if(low[u]==dfn[u]) { int t; col++; do { t=q.top(); q.pop(); vis[t]=-1; color[t]=col; } while(u!=t); } } int main() { memset(vis,0,sizeof(vis)); memset(color,0,sizeof(color)); memset(dfn,0,sizeof(dfn)); memset(low,0,sizeof(low)); memset(in,0,sizeof(in)); memset(out,0,sizeof(out)); num=col=0; int temp,ed; scanf("%d",&n); for(int i=1; i<=n; i++) { while(~scanf("%d",&temp)&&temp) { wakaka[i].push_back(temp); } } for(int i=1; i<=n; i++) { if(vis[i]==0) { tarjan(i); } } if(col==1)printf("%d\n%d\n",1,0); else { int t1=0,t2=0; for(int i=1; i<=n; i++) { int t=color[i]; int flag=0; int len=wakaka[i].size(); for(int j=0; j<len; j++) { int temp=wakaka[i][j]; if(color[temp]!=t) { in[color[temp]]++; out[t]++; } } } for(int i=1; i<=col; i++) { if(in[i]==0)t1++; if(out[i]==0)t2++; } printf("%d\n%d\n",t1,max(t1,t2)); } return 0; }