poj3522

给定一个简单图,n个点,m条边( 1<=n<=100,0 ≤ m ≤ n(n − 1)/2 ),要求一颗生成树,使得其最大边与最小边的差值是所有生成树中最小的,输出最小的那个差值。

思路:枚举所有边,用kruskal求生成树,不断更新最小值就可以了。 

优化:可以先找到所有节点的最大边中的最小值,枚举到这条边就可以结束了。

代码只写出思路,没时间测试,仅供参考。

struct Edge {
  int src;
  int dst;
  int len;
}

int n;
vector<Edge> sorted_graph;
vector<int> father;
vector<int> degree;

void Union(int node_a, int node_b) {
  int father_a = Find(node_a);
  int father_b = Find(node_b);
  if (father_a < 0 || father_b < 0 ||father_a >= n || father_b >= n) {
    assert(0);
    return;
  }
  if (degree[father_a] > degree[father_b]) {
    father[father_b] = father_a;
    degree[father_a] += degree[father_b];
  } else {
    father[father_a] = father_b;
    degree[father_b] += degree[father_a];
  }
}

int Find(int node_a) {
  if (father[node_a] == node_a) return node_a;
  return father[node_a] = Find(father[node_a]);
}

vector<Edge> Kruska(int pos) {
  vector<Edge> tree;
  for (int i = 0; i < n; ++i) {
    father[i] = i;
    degree[i] = 1;
  }
  for (int i = pos; pos < sorted_graph.size(); ++i) {
    const Edge& e = sorted_graph[i];
    if (Find(e.src) != Find(e.dst)) {
      Union(e.src, e.dst);
      tree.push_back(e);
    }   
    if (tree.size() == n - 1) {
      return tree;
    }   
  }
  return vector<Edge>();
}

int main() {
  GenerateGraph();
  SortEdges();
  int min_interval = 0x7fffffff;
  bool min_tree_exist = false;
  for (int i = 0; i < sorted_graph.size(); ++i) {
    vector<Edge> res = Kruska(i);
    if (res.size() < n - 1) {
      continue;
    }   
    min_interval = min(min_interval, res.back().len - res.front().len); 
    min_tree_exist = true;
  }
  if (min_tree_exist) {
    cout << "The result is " << min_interval << endl;
  } else {
    cout << "The tree is not exist!" << endl;
  }
  return 1;
}

 

posted @ 2013-09-10 00:26  dmthinker  阅读(140)  评论(0)    收藏  举报