The Unique MST POJ

来源:互联网 发布:fft的c语言实现 编辑:程序博客网 时间:2024/06/07 05:32

题目链接:POJ1679

题目:判断是否有唯一一个最小生成树。

1.在网上看了好多的代码。。。板子上kuangbin大神次小生成树的代码竟然就是个求最小生成树的。。。。并不完整。

他的博客上倒是有完整的  先码住

kuangbin


 求最小生成树时,用数组Max[i][j]来表示MST中i到j最大边权 求完后,直接枚举所有不在MST中的边,替换掉最大边权的边,更新答案

    #include <iostream>      #include <cstdio>      #include <cstring>      #include <algorithm>      #include <cmath>      #define inf 0x3f3f3f3f      #define ms(x) memset(x, 0, sizeof(x))      using namespace std;      const int N = 110;      bool vis[N];      int lowc[N];      int pre[N];      int Max[N][N];      bool used[N][N];      int prime(int cost[][N], int n)  //kuangbin的板子    {          int ans = 0;          ms(vis);          ms(Max);          ms(used);          vis[0] = true;          pre[0] = -1;          for(int i=1; i<n; i++)          {              lowc[i] = cost[0][i];              pre[i] = 0;          }          lowc[0] = 0;          for(int i=1; i<n; i++)          {              int mic = inf;              int p = -1;              for(int j=0; j<n; j++)                  if(!vis[j] && mic>lowc[j])                  {                      mic = lowc[j];                      p = j;                  }              if(mic == inf ) return -1;              ans+=mic;              vis[p] = true;              used[p][pre[p]]= used[pre[p]][p] = true;              for(int j=0; j<n; j++)              {                  if(vis[j]) Max[j][p] = Max[p][j] = max(Max[j][pre[p]], lowc[p]);                  if(!vis[j] && lowc[j] > cost[p][j])                  {                      lowc[j] = cost[p][j];                      pre[j] = p;                  }              }          }          return ans;      }      int ans ;      int smst(int cost[][N], int n)  //求次小生成树    {          int mi =inf;          for(int i=0;i<n;i++)          {              for(int j=i+1;j<n;j++)              {                  if(cost[i][j]!=inf && !used[i][j])                  {                      mi = min(mi, ans+cost[i][j] - Max[i][j]);                  }              }          }          if(mi == inf) return -1;          return mi;      }      int cost[N][N];      int main()      {          int T;          scanf("%d",&T);          while(T--)          {              int n,m;              scanf("%d%d",&n,&m);              for(int i=0;i<n;i++)              {                  for(int j=0;j<n;j++)                  {                      if(i==j) cost[i][j] = 0;                      else cost[i][j] = inf;                  }              }              while(m--)              {                  int x, y, z;                  scanf("%d%d%d",&x,&y,&z);                  x--, y--;                  cost[x][y] = cost[y][x] = z;              }              ans = prime(cost,n);              if(ans == -1)              {                  printf("Not Unique!\n");              }              else if(ans == smst(cost, n))                  printf("Not Unique!\n");              else printf("%d\n",ans);          }          return 0;      }  

2.

另外这个博客比较易懂

有待整理。。

思路2.1       用prim 时, 如果有两个符合条件且权值相同的边, 则最小生成树不唯一。

2.2   kruskal   先建个最小生成树, 并用个数组记录下边的id。

枚举边,建树时跳过这些边。如果权值一样, 则不唯一

原创粉丝点击