读书人

次小生成树有关问题探讨

发布时间: 2013-09-17 13:35:59 作者: rapoo

次小生成树问题探讨
次小生成树有关问题探讨次小生成树有关问题探讨

??????? 只要最小生成树和次小生成树权值和一样就唯一。因此得出如下算法,首先计算出最小生成树T,然后对最小生成树上任意不相邻的两个点 uv添加最小生成树以外的存在的边形成环,然后寻找u与v之间最小生成树上最长的边删去,计算map[i][j]与 maxd[i][j差值,求出最小的来,如果是0,就说明MST和次小生成树一样。

//顶点数100,看成了1000,一个MLE,改了立马AC,嘿嘿
//这道题目,AC率很低
import java.util.Scanner;
public class POJ1679 {
  static int maxn = 105;
  static int[][] map = new int[maxn][maxn];
  static int[][] maxd = new int[maxn][maxn];
  static int[] father = new int[maxn];
  static int[] dist = new int[maxn];
  static boolean[] vis = new boolean[maxn];
  static int n,m;
  
  public static void main(String[] args) {
    
    Scanner sc= new Scanner(System.in);
    int num = sc.nextInt();
    int u,v,w;
    while(num-->0) {
      n = sc.nextInt();
      m = sc.nextInt();
      for(int i=1; i<=n; i++) {
        for(int j=1; j<=n; j++) {
          if(i==j) {
            map[i][j] = 0;
          }else {
            map[i][j] = 0x3f3f3f3f;
          }
          maxd[i][j] = -1;
        }
      }
      for(int i=0; i<m; i++) {
        u = sc.nextInt();
        v = sc.nextInt();
        w = sc.nextInt();
        map[u][v] = w;
        map[v][u] = w;
      }
      int ans = prime();
      int min = 0x3f3f3f3f;
      for(int i=1; i<=n; i++) {
        for(int j=1; j<=n; j++) {
          boolean tag = i!=j&&map[i][j]!=0x3f3f3f3f
              &&father[i]!=j&&father[j]!=i;
          if(tag) {
            if(min>map[i][j]-maxd[i][j]) {
              min = map[i][j]-maxd[i][j];
            }
          }
        }
      }
      if(0==min) {
        System.out.println("Not Unique!");
      }else {
        System.out.println(ans);
      }
    }
  }
  private static int prime() {
    
    int ans = 0;
    for(int i=1; i<=n; i++) {
      dist[i] = map[1][i];
      father[i] = 1;
      vis[i] = false;
    }
    vis[1] = true;
    //存放MST节点
    int stack[] = new int[n+1];
    int top = 0;
    stack[top++] = 1;
    for(int i=1; i<n; i++) {
      
      int next = 1;
      int min = 0x3f3f3f3f;
      for(int j=1; j<=n; j++) {
        if(!vis[j]&&min>dist[j]) {
          next = j;
          min = dist[j];
        }
      }
      vis[next] = true;
      ans += min;
      
      //dp
      for(int k=0; k<top; k++) {
        maxd[next][stack[k]] = maxd[stack[k]][next]
            = Math.max(min,maxd[father[next]][stack[k]]);
            
      }
      stack[top++] = next;
      for(int t=1; t<=n; t++) {
        if(!vis[t]&&dist[t]>map[next][t]) {
          dist[t] = map[next][t];
          father[t] = next;
        }
      }
    }
    return ans;
  }
}

??????? 接下来该看数据挖掘十大算法了。

读书人网 >编程

热点推荐