Transferring Sylla
首先。什么是k连通图?
k连通图就是指至少去掉k个点使之不连通的图。
题目:
题目描写叙述的非常裸。就是给你一张图要求你推断这图是否是3-连通图。
算法分析:
/////////////////////////////////////////////////////////////////////
(网上别人的分析,分析的非常好所以直接引用了)
/////////////////////////////////////////////////////////////////////////
可是这肯定超时。
所以。我们还要优化。我们能够想到既然枚举两个点会超时。那么如今我仅仅枚举一个点呢?当然是能够的。
可是,为什么能够仅仅枚举一个点呢?由于,我们从割点的定义能够知道当一个图是强连通图时候,那么他一定没有割点。
所以。当我们枚举到了删除点的时候。那么在剩下的图中假设存在割点那个这个图一定不是3-连通图。由于。此时我们仅仅要删除两条边就能够使其不连通了。
给出求解割点割边的模板,这题仅仅要一套模板就能够了。
///////////// DATA ///////////////////// vector<int> G[MAXN]; int V,E; bool cut[MAXN]; // 是否是割点 int color[MAXN]; //0:没有訪问 1:正在訪问 2:已经訪问 int lowc[MAXN]; //表示i及i的子孙相连的辈分最高的祖先节点所在的深度 int d[MAXN]; //表示i节点在树中的深度 int root; //根节点 int fath; //父节点 int pcnt; //割点个数 int egcnt; //割边个数 bool flag; //是否存在割点 ///////////// DATE END //////////////////////// //初始化 void init(){ flag = false; for(int i = 0;i <= V;++i) G[i].clear(); } ///////////////// Tarjan ////////////////////// void dfs(int u,int fa,int deep){ color[u] = 1; //正在訪问 lowc[u] = d[u] = deep; // 深度 int tot = 0; //子树个数 int i,v; for(i = 0;i < (int)G[u].size();++i){ v = G[u][i]; if(v != fa&&color[v] == 1){ lowc[u] = min(lowc[u],d[v]); } if(0 == color[v]){ dfs(v,u,deep + 1); tot++; //子树 +1 lowc[u] = min(lowc[u],lowc[v]); //求割点 if((u == root&&tot > 1)||(u != root&&lowc[v] >= d[u])){ cut[u] = 1; //不能将pcnt++写到这里 flag = true; } /* //求割边 u - > v是割边 if(lowc[v] > d[u]){ edge[u][v] = true; } */ } } color[u] = 2; } //////////// END Tarjan /////////////// void calc(int del){ pcnt = egcnt = 0; memset(cut,0,sizeof(cut)); memset(color,0,sizeof(color)); memset(lowc,0,sizeof(lowc)); memset(d,0,sizeof(d)); color[del] = 2; root = 0; if(del == 0) root = 1; dfs(root,-1,1); /* //统计割点个数 for(int i = 0;i < V;++i) if(cut[i]) pcnt++; */ } //求图是否是三连通 void solve(){ for(int i = 0;i < V;++i){ calc(i); //推断图是否连通 for(int j = 0;j < V;++j){ if(0 == color[j]){ flag = true; break; } } if(flag) break; } }