POJ - 3352 无向图的割和桥以及双连通分量
双连通分量是指图中每两个点都有两条完全不同的路径可到达..也就是去掉这个图的任意一个边一个点...两两之间依然可达..
图论中的桥...在有向图中是两个连通分量之间唯一的边(如果有多条那么都不是桥)...在无向图中是两个双连通分量之间的唯一边...
而割指的是割点..割点肯定是和桥的端点...但桥的端点不一是割点..如:
(1,4),(2,4),(3,4),(4,5),(4,6),(4,7)都是桥..所有点都是桥的端点...但是只有4是割点...1,2,3,5,6,7都不是割点..
去掉一个连通图中的一个桥或者割点..这个连通图就将成为不连通的多个连通图..
求无向图中的桥的方法是有Tarjan发明的..Byvoid大大的讲解很给力: DFN ( 终点 ) < LOW ( 起点 ) 的边就是桥...这条边的"终点"就是割点..
回到POJ3352...题目给出了连通的无向图..并且两点直接最多只有一条边...求的是加几条边能使得该无向图整个变成一个双连通图..
那么先对图做无向图的Tarjan...得到每个点所在的双连通记录在Low里....可以想象一下..如果把所有的双连通分量分别缩成一个点...那么整个图就是一棵树了..如果给一棵树..要史其成为一个双连通图...那么需要加( 叶子结点数+1)/2调边...
这道题就是在做完Tarjan找作为叶子节点的双连通分量的个数k..然后答案就是(k+1)/2...
Program:
// POJ3352 加边做双连通图#include#include#include#define MAXN 5001using namespace std;struct pp{ int x,y,next; }line[MAXN*5];int n,m,link[MAXN],i,p,low[MAXN],dfn[MAXN],tp[MAXN],numtp,sum[MAXN];bool instack[MAXN],used[MAXN];stack mystack;void trajin(int h){ int k; instack[h]=true; mystack.push(h); low[h]=dfn[h]=++p; k=link[h]; while (k) { if (!dfn[line[k].y]) { trajin(line[k].y); low[h]=min(low[h],low[line[k].y]); }else if (instack[line[k].y]) { low[h]=min(low[h],dfn[line[k].y]); } k=line[k].next; } k=h; if (low[k]==dfn[k]) { numtp++; do { k=mystack.top(); tp[k]=numtp; mystack.pop(); instack[k]=false; }while ( low[k]!=dfn[k]); } return; } void getanswer(){ int i; memset(instack,false,sizeof(instack)); while (!mystack.empty()) mystack.pop(); memset(tp,0,sizeof(tp)); memset(dfn,0,sizeof(dfn)); p=0; numtp=0; for (i=1;i<=n;i++) if (!dfn[i]) trajin(i); for (i=1;i<=n;i++) if (!tp[i]) { printf("\n"); return; } memset(link,0,sizeof(link)); memset(sum,0,sizeof(sum)); for (i=1;i<=m;i++) if (tp[line[i].x]!=tp[line[i].y]) { p++; sum[tp[line[i].x]]++; } for (i=1;i<=n;i++) if (!sum[tp[i]]) printf("%d ",i); printf("\n"); return;}int main(){ while (~scanf("%d%",&n)) { if (!n) break; scanf("%d",&m); memset(link,0,sizeof(link)); memset(line,0,sizeof(line)); for (i=1;i<=m;i++) { scanf("%d%d",&line[i].x,&line[i].y); line[i].next=link[line[i].x]; link[line[i].x]=i; } getanswer(); } return 0; }
版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。
暂时没有评论,来抢沙发吧~