POJ 3723 Conscription 最小生成树 克鲁斯卡尔算法变形

2015-11-21 01:02:24 · 作者: · 浏览: 7

?

#include 
  
   
#include 
   
     #include 
    
      #include 
     
       #include 
      
        #include 
       
         #include 
        
          #include 
         
           #include
           #include 
           
             #include 
            
              #define INF 100000000 using namespace std; int n,m,r; struct node{ int x,y,w; bool operator < (const node &a)const{ return w < a.w; } }; int fa[20005]; int fun(int x){ if(fa[x] == x) return x; else return fa[x] = fun(fa[x]); } int main(){ int t; cin >> t; while(t--){ priority_queue
             
               que; scanf("%d%d%d",&n,&m,&r); for(int i = 0;i < r;i++){ node cc; scanf("%d%d%d",&cc.x,&cc.y,&cc.w); cc.y += 10000; que.push(cc); } long long int ans = 0; for(int i = 0;i < n;i++){ fa[i] = i; } for(int i = 10000;i < m+10000;i++){ fa[i] = i; } while(!que.empty()){ node cc = que.top(); que.pop(); if(fun(cc.x) != fun(cc.y)){ fa[fun(cc.x)] = fun(cc.y); ans += cc.w; } } cout << (long long)(n+m)*10000- ans << endl; } return 0; } 
             
            
           
         
        
       
      
     
    
   
  

克鲁斯卡尔求最小生成树的思想是利用了从一个集合到另外一个集合的最小的边一定包含在这两个集合中点的最小生成树之中。同理这道题求得其实是这些点的最大生成树,同样可以用这种方法计算。

?

?