HDU 3749(点双连通分量-并查集)



目的:就是说任意图中的两点之间有几条点不重复的路径(如果是只有2个点,一个 边,则它只有一条)如果点与点之间没有边的链接,则路径数为0。 方法:因为图中可能含有割点,导致有的点可能会被涂上多种颜色,所以就使用belong_col 容器来存放,eg:belong_col[a].push_back(col)表示点a在颜色为col的点双连通分量里, 因为两点一线也是点双连通分量,但从题目的意思看它是1。 一组数据(有割点,有多子图) 7 5 50 0 1 1 2 0 2 2 3 4 5

#include
   
   
    
    
#include
    
    
     
     
#include
     
     
      
      
#include
      
      
       
       
#include
       
       
         #define mm(x) memset(x,0,sizeof(x)) using namespace std; const int N=5000+5; vector 
        
          G[N]; vector 
         
           belong_col[N]; int dfn[N],low[N],paint[N],num[N],index,col,node[N]; int father[N]; int n; struct edge { int f,t; }; stack 
          
            s; int MIN(int a,int b) { if(a 
           
             =dfn[u]) { mm(node); while(1) { edge e=s.top(); s.pop(); node[e.f]++;node[e.t]++; belong_col[e.f].push_back(col); belong_col[e.t].push_back(col); if(e.f==u) break; } num[col]=cal();//一个点-双连通子图的点的个数 col++; } } else if(v!=f&&dfn[u]>dfn[v]) { edge e; e.f=u;e.t=v; low[u]=MIN(low[u],dfn[v]); } } } int main() { int m,q; int ca=1; while(~scanf("%d%d%d",&n,&m,&q),n+m+q) { Init(n); while(m--) { int a,b; scanf("%d%d",&a,&b); G[a].push_back(b); G[b].push_back(a); int ra=find_set(a); int rb=find_set(b); if(ra!=rb) { father[ra]=rb; } } for(int i=0;i 
            
              2) { printf("two or more\n"); mark=1;break; } } } if(mark) { falg=1; break; } } if(!falg) printf("one\n"); } } return 0; } 
             
            
           
          
         
       
      
      
     
     
    
    
   
   

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值