首页 > 代码库 > poj 3352 求 边-双连通分量
poj 3352 求 边-双连通分量
【题意】 给出一张无向连通图,求至少连几条边可以变成边双连通图
【思路】求出边-双连通分量,缩点就成了一棵树,求这棵树里的出度为1 的点num 结果是(num-1)/2;
1 #include<iostream> 2 #include<stdio.h> 3 #include<string.h> 4 #include<stack> 5 #include<vector> 6 using namespace std; 7 int pre[1002],low[1002],n,adj[1002],num,c,du[1002]; 8 struct E 9 {10 int to;11 int next;12 } edge[500000];13 14 void add(int a,int b)15 {16 edge[num].to=b;17 edge[num].next=adj[a];18 adj[a]=num++;19 }20 21 int dfs(int u,int fa)22 {23 int i,v,lowv;24 pre[u]=low[u]=c++;25 for(i=adj[u]; i!=-1; i=edge[i].next)26 {27 int v;28 v=edge[i].to;29 if(v!=fa&&pre[v]<pre[u])30 {31 if(!pre[v])32 {33 lowv=dfs(v,u);34 low[u]=min(low[u],lowv);35 }36 else if(pre[v]&&v!=fa)37 low[u]=min(low[u],pre[v]);38 }39 }40 return low[u];41 }42 43 int main()44 {45 int a,b,m,i,v;46 while(~scanf("%d%d",&n,&m))47 {48 memset(adj,-1,sizeof(adj));49 num=0;50 while(m--)51 {52 scanf("%d%d",&a,&b);53 add(a,b);54 add(b,a);55 }56 c=1;57 memset(pre,0,sizeof(pre));58 for(int i=1; i<=n; i++)59 if(pre[i]==0)60 dfs(i,-1);61 memset(du,0,sizeof(du));62 for(int u=1; u<=n; u++)63 {64 for(i=adj[u]; i!=-1; i=edge[i].next)65 {66 int v;67 v=edge[i].to;68 if(low[u]!=low[v])69 {70 du[low[u]]++;71 du[low[v]]++;72 }73 }74 }75 int ans=0;76 for(int i=0; i<=n; i++)77 if(du[i]/2==1)78 ans++;79 printf("%d\n",(ans+1)/2);80 }81 return 0;82 }
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。