HDOJ HDU 1863 畅通工程 ACM 1863 IN HDU

MiYu原创, 转帖请注明 : 转载自 ______________白白の屋

题目地址:
         http://acm.hdu.edu.cn/showproblem.php?pid=1863
题目描述:
畅通工程

Time Limit: 
1000 / 1000  MS (Java / Others)    Memory Limit:  32768 / 32768  K (Java / Others)
Total Submission(s): 
5783     Accepted Submission(s):  2128


Problem Description
省政府“畅通工程”的目标是使全省任何两个村庄间都可以实现公路交通(但不一定有直接的公路相连,只要能间接通过公路可达即可)。经过调查评估,得到的统计表中列出了有可能建设公路的若干条道路的成本。现请你编写程序,计算出全省畅通需要的最低成本。
 

Input
测试输入包含若干测试用例。每个测试用例的第1行给出评估的道路条数 N、村庄数目M ( 
<   100  );随后的 N 
行对应村庄间道路的成本,每行给出一对正整数,分别是两个村庄的编号,以及此两村庄间道路的成本(也是正整数)。为简单起见,村庄从1到M编号。当N为0时,全部输入结束,相应的结果不要输出。
 

Output
对每个测试用例,在1行里输出全省畅通需要的最低成本。若统计数据不足以保证畅通,则输出“
? ”。
 

Sample Input
3   3
1   2   1
1   3   2
2   3   4
1   3
2   3   2
0   100
 

Sample Output
3
?

题目分析:
最小生成树的问题.  --->  用 prim 或者 kruskal 算法求解, 我是用的kruskal算法.

按边的值做非降序排列, 然后从小到大对每条边一次判断, 如果2个顶点未全部访问或者不在同一个集合,那么加上这条边.直到最后一条边.
最后判断一下图的连通性,如果不是连通的, 输出 ? , 否则输出已选则的边的总和.

做这个题的时候WA了6次,  一直找不到原因, 没办法的情况下,又把数据结构的书翻出来,把 kruskal
算法复习了一遍, 再次检查代码, 发现问题了,  算法的过程是一条边一条边的加入集合内, 我居然NC
的在输入的时候就全部加入集合了, 结构导致 kruskal 算法的断言没有起到作用. YM. 

代码如下:
MiYu原创, 转帖请注明 : 转载自 ______________白白の屋

#include 
< iostream >
#include 
< algorithm >
using   namespace  std;
typedef 
struct  {
     
int  parent;
     
int  height;   
}Tset;  

typedef 
struct  treeUFS{
       
public :
              treeUFS(
int  n  =   0 ):N(n + 1 ) {  set   =   new  Tset[N];
                                          visited 
=   new   bool [N]; 
                                          
for  (  int  i  =   0 ; i  !=  N;  ++  i) 
                                          
set [i].parent  =  i, set [i].height  =   1 ,visited[i]  =   false
                                        }
              
~ treeUFS(){ delete []  set ; };
              
int  find (  int  x ){   int  r  =  x;   while  ( r  !=   set [r].parent ) r  =   set [r].parent;
                                   
return  r;
                                }
              
void  init () {  for  (  int  i  =   0 ; i  !=  N;  ++  i) 
                             
set [i].parent  =  i, set [i].height  =   1 ,visited[i]  =   false ;  }
              
void  setVisit (  int  x,  int  y ) { visited[x]  =  visited[y]  =   true ; } 
              
bool  getVisit (  int  x ) {  return  visited[x]; }
              
void  Merge(  int  x, int  y ){  x  =  find ( x );  y  =  find ( y );  
                                           
if  ( x  ==  y )  return ;
                                           
if  (  set [x].height  ==   set [y].height ){
                                                
set [y].parent  =  x;
                                                
set [x].height  ++ ;
                                           }
                                           
else   if  (  set [x].height  <   set [y].height ) {
                                                     
set [x].parent  =  y;       
                                                   }
                                           
else {    set [y].parent  =  x;
                                               }
                                        }
              
int  getTreeCount (){  int  nCount  =   0 for  (  int  i  =   1 ; i  <  N;  ++  i ){
                                                         
if  ( find (i)  ==  i ){
                                                              nCount 
++
                                                         }
                                                   }
                                   
return  nCount;
                                 }
       
private :
              Tset 
* set ;
              
bool   * visited;
              
int  N;         
}treeUFS; 
typedef 
struct  edge {
       
int  v1;
       
int  v2;
       
int  wei;     
}EDGE;
EDGE edge[
10005 ];
bool  cmp ( EDGE A, EDGE B )
{
     
return  A.wei  <  B.wei; 
}
int  main ()
{
    
int  N,M;
    
while  ( scanf (  " %d%d " , & N, & M ) , N )
    {
            
int  v1,v2;
            
if  ( M  ==   0  )
            {
                 puts ( 
" ? "  );
                 
continue ;
            }
            memset ( edge, 
0  ,  sizeof  ( edge ) );
            treeUFS UFS ( M ); 
            
for  (  int  i  =   1 ; i  <=  N;  ++  i ) 
            {
                  scanf ( 
" %d%d " & edge[i].v1, & edge[i].v2 );
                  scanf ( 
" %d " & edge[i].wei );
            } 
            sort ( edge 
+   1 , edge  +  N  +   1 , cmp );
            
int  sum  =   0 ;
            
for  (  int  i  =   1 ; i  <=  N;  ++  i )
            {
                  
if  ( (  ! UFS.getVisit(edge[i].v1)  ||   ! UFS.getVisit(edge[i].v2) )  ||  UFS.find(edge[i].v1)  !=  UFS.find(edge[i].v2) )
                  {
                        UFS.setVisit ( edge[i].v1, edge[i].v2 );
                        UFS.Merge ( edge[i].v1, edge[i].v2 );
                        sum 
+=  edge[i].wei;
                  }        
            }
            
int  tCount  =  UFS.getTreeCount();
            
if  ( tCount  !=   1  )
            {
                 puts ( 
" ? "  );
                 
continue
            }
            printf ( 
" %d\n " ,sum );
    }
    
return   0
}

你可能感兴趣的:(HDOJ HDU 1863 畅通工程 ACM 1863 IN HDU)