CCF201812-4 数据中心

题解: 求最小生成树的最大边
一开始想的是先求最小生成树,然后以root节点进行一次DFS,来搜索这棵树的最大边(因为要考虑这个无向图存在多棵树的情况) 交了一发AC了…
然后再试了一下不用DFS搜索,直接求无向图的最小生成树中的最大边,也AC了… 果不其然,是老子想多了…


#include
#include
#include
#include
using namespace std ;
int inf = 0x3f ;
const int maxn = 1e5 +10 ;
int pre[maxn] ;
struct node{
  int a , b, c ;
}st[maxn];
int find(int x)
{
    int r=x;
    while(pre[r]!=r)
    r=pre[r];//找到他的前导结点
   int i=x,j;
    while(i!=r)//路径压缩算法
    {
        j=pre[i];//记录x的前导结点
        pre[i]=r;//将i的前导结点设置为r根节点
        i=j;
    }

    return r;
}

bool cmp(node a , node b ) {
 return a.c < b.c ;
}
int cnt = 0 ;
void init(int n){
    cnt = 0 ;
 for(int i = 1 ; i <= n ; i++){
    pre[i] = i ;
 }
}

// 链式前向星
int head[maxn] ;
int max_cap = -1 ;
int vis[maxn] ;
struct Node{
 int to , next , cap ;
}num[maxn];
void Init() {
  cnt = 0 ;
  memset(head , -1 , sizeof(head))  ;
  memset(vis , 0 , sizeof(vis)) ;
}

void Add_edge(int u , int v , int w){
     num[cnt].to = v ;
     num[cnt].cap = w ;
     num[cnt].next = head[u] ;
     head[u]  = cnt ++ ;
}
// 结束

void DFS(int root , int u , int deep , int ans ){
      vis[u] = 1 ;
      for(int i = head[u] ; i != -1 ; i = num[i].next){
            int v = num[i].to ;
            int w = num[i].cap ;
            if(vis[v] == 0 ){
                DFS(root , v , deep + 1 , max_cap = max(max_cap , num[i].cap) ) ;
            }
      }

}
int main(){

  int n , m , r  ;
  cin >> n >> m >> r ;
  init(n) ;
  int u , v , w;
  for(int i = 0 ; i < m ; i++){
    cin >> u >> v >> w ;
    st[cnt].a = u  ;
    st[cnt].b = v ;
    st[cnt++].c = w ;
  }
  sort(st , st + m , cmp) ;
   Init() ;
   int maxn = -1 ;
  for(int i = 0 ; i < m ; i++){
       int r = find(st[i].a) ;
       int l = find(st[i].b) ;
       if(r != l ) {
        pre[r] = l ;
        //Add_edge(st[i].a , st[i].b , st[i].c ) ;
        //Add_edge(st[i].b , st[i].a , st[i].c)  ;
        maxn = max(maxn , st[i].c) ;
       }

  }
  // DFS(r , r , 1 , -1) ;
  // cout << max_cap <

你可能感兴趣的:(最小生成树,CCF)