最长可链接字符串数目(bellmanford)

有n 个长为m+1 的字符串,如果某个字符串的最后m 个字符与某个字符串的前m 个字符匹配,则两个字符串可以联接,
问这n 个字符串最多可以连成一个多长的字符串,如果出现循环,则返回错误。

随手写,未经编译,只保证思想,不保证正确性。

使用bellman-ford的时间复杂度较高,如果入度为0的点有m个,e为边数量,则时间为O(mnE)

//有n 个长为m+1 的字符串,如果某个字符串的最后m 个字符与某个字符串的前m 个字符匹配,则两个字符串可以联接,
//问这n 个字符串最多可以连成一个多长的字符串,如果出现循环,则返回错误。
int node_num;
vector<vector<int> > graph; // 邻接矩阵,如果两者不相连,不存储
vector<int> srcs;
// 获取srcs,入度为0的顶点
void GetSrcs() {
  srcs.clear();
  vector<int> degrees;
  degrees.resize(node_num, 0); 
  for (int i = 0; i < node_num; ++i) {
    for (int j = 0; j < graph[i].size(); ++j) {
      degrees[graph[i][j]] += 1;
    }   
  }
  for (int i = 0; i < node_num; ++i) {
    if (degrees[i] == 0) srcs.push_back(i);
  }
}

bool BellmanFord(int* max_len, int src) {
  int tmp_max = -1; 
  vector<int> max_lens;
  max_lens.resize(node_num, -1);
  max_lens[src] = 0;
  for (int i = 0; i < graph[src].size(); ++i) {
    max_lens[graph[src][i]] = 1;
  }
  for (int i = 2; i < node_num; ++i) {
    for (int j = 0; j < node_num; ++j) {
      for (int k = 0; k < graph[j].size(); ++k) {
        if (max_lens[j] < max_lens[graph[j][k]] + 1) {
          if (max_lens[graph[j][k]] >= 0) { // 只有src到graph[j][k]可达,才更新距离
            max_lens[j] = max_lens[graph[j][k]] + 1;
            tmp_max = max(tmp_max, max_lens[j]);
          }   
        }   
      }   
    }   
  }
  // 第n次更新,如果仍然能更新max的值,说明存在环路
  for (int j = 0; j < node_num; ++j) {
    for (int k = 0; k < graph[j].size(); ++k) {
      if (max_lens[j] < max_lens[graph[j][k]] + 1) {
        return false;
      }   
    }   
  }
  *max_len = tmp_max;
  return true;
}

int GetMaxLen() {
  int max_len = -1; 
  for (int i = 0; i < srcs.size(); ++i) {
    int part_max_len = 0;
    if (!BellmanFord(&part_max_len, srcs[i])) continue;
    max_len = max(max_len, part_max_len);
  }
  return max_len;
}

 

 

 

posted @ 2013-09-01 21:13  dmthinker  阅读(187)  评论(0)    收藏  举报