• POJ1679判断最小生成树的唯一性


    题意:
         判断最小树是否唯一。
    思路:
         我用了两种方法,主要就是好久没敲了,找个水题练练手,第一种就是先一遍最小生成树,然后枚举最小生成树上的每一条边,然后取消这条边,在跑一遍最小生成树,就这样一直跑最小生成树,如果找到了一颗和之前的那个一样的,那么就是不唯一,第二种方法也是先最小树,然后枚举,在枚举的时候不是继续重新跑,而是断开当前边,把树分成两个集合<两次深搜实现>,然后在枚举这连个集合之间是否可以找到一个可以代替当前枚举的最小树的边,实现复杂度的话应该是第二种快点,但理论上也快不多少,只是为了练练手,在多说一句,第二种方法和求次小树的思路有点像,但是次小树可以再这个上面进行dp优化,其实这个题目也可以直接判断次小树是否等于最小树。好像有点说多了。




    #include<stdio.h>
    #include<string.h>
    #include<algorithm>


    #define N 110


    using namespace std;


    typedef struct
    {
       int x ,y ,c;
    }EDGE;


    EDGE edge[N*N];
    int  mer[N] ,mst[N];


    int finds(int x)
    {
       return x == mer[x] ? x : mer[x] = finds(mer[x]);
    }


    bool camp(EDGE a ,EDGE b)
    {
       return a.c < b.c;
    }


    int MST(int n ,int m ,int co)
    {
       for(int i = 1 ;i <= n ;i ++)mer[i] = i;
       int Ans = 0 ,sum = 0;
       for(int i = 1 ;i <= m ;i ++)
       {
          if(i == co) continue;
          int xx = finds(edge[i].x);
          int yy = finds(edge[i].y);
          if(xx != yy) 
          {
             Ans += edge[i].c ,sum ++ ;
             mer[xx] = yy;
             if(co == -1) mst[sum] = i;
          }
          if(sum == n - 1) break;
       }
       return Ans;

       


    int main ()
    {
       int t ,i ,n ,m;
       scanf("%d" ,&t);
       while(t--)
       {
          scanf("%d %d" ,&n ,&m);
          for(i = 1 ;i <= m ;i ++)
          scanf("%d %d %d" ,&edge[i].x ,&edge[i].y ,&edge[i].c);
          sort(edge + 1 ,edge + m + 1 ,camp);
          int Ans = MST(n ,m ,-1);
          for(i = 1 ;i < n ;i ++)
          {
             int tmp = MST(n ,m ,mst[i]);
             if(Ans == tmp) break;
          }
          i == n || m == n - 1? printf("%d " ,Ans) : puts("Not Unique!");
       }
       return 0;
    }
          
         
          
          
          
       
    #include<stdio.h>
    #include<string.h>
    #include<algorithm>


    #define N 110


    using namespace std;


    typedef struct
    {
       int x ,y ,c;
    }EDGE;


    typedef struct
    {
       int to ,next;
    }STAR;


    EDGE edge[N*N];
    STAR E[N*N];
    int  map[N][N] ,mer[N] ,mark[N];
    int list[N] ,tot ,mst[N];
    int L[N] ,R[N] ,ll ,rr;


    void add(int a, int b)
    {
       E[++tot].to = b;
       E[tot].next = list[a];
       list[a] = tot;
    }


    int finds(int x)
    {
       return x == mer[x] ? x : mer[x] = finds(mer[x]);
    }


    int minn(int x ,int y)
    {
       return x < y ? x : y;
    }


    bool camp(EDGE a ,EDGE b)
    {
       return a.c < b.c;
    }


    int MST(int n ,int m)
    {
       for(int i = 1 ;i <= n ;i ++) mer[i] = i;
       int Ans = 0 ,sum = 0;
       memset(list ,0 ,sizeof(list)) ,tot = 1;
       for(int i = 1 ;i <= m ;i ++)
       {
          int xx = finds(edge[i].x);
          int yy = finds(edge[i].y);
          if(xx != yy) 
          {
             Ans += edge[i].c ,sum ++;
             mer[xx] = yy;
             mst[sum] = i;
             add(edge[i].x ,edge[i].y);
             add(edge[i].y ,edge[i].x);
          }
          if(sum == n - 1) break;
       }
       return Ans;
    }


    void DFS1(int x)
    {
       for(int k = list[x] ;k ;k = E[k].next)
       {
          int to = E[k].to;
          if(mark[to]) continue;
          mark[to] = 1;
          L[++ll] = to;
          DFS1(to);
       }
    }


    void DFS2(int x)
    {
       for(int k = list[x] ;k ;k = E[k].next)
       {
          int to = E[k].to;
          if(mark[to]) continue;
          mark[to] = 1;
          R[++rr] = to;
          DFS2(to);
       }
    }




    int main ()
    {
       int t ,n ,m ,i ,j ,mk;
       scanf("%d" ,&t);
       while(t--)
       {
           scanf("%d %d" ,&n ,&m);
           for(i = 1 ;i <= n ;i ++)
           for(j = 1 ;j <= n ;j ++)
           map[i][j] = 100000000;
           for(i = 1 ;i <= m ;i ++)
           {
              scanf("%d %d %d" ,&edge[i].x ,&edge[i].y ,&edge[i].c); 
              int x = edge[i].x ,y = edge[i].y;
              map[x][y] = map[y][x] = minn(map[x][y] ,edge[i].c);
          }
          sort(edge + 1 ,edge + m + 1 ,camp);
          int Ans = MST(n ,m);
          if(m == n - 1)
          {
             printf("%d " ,Ans);
             continue;
          }
          mk = 0;
          for(i = 1 ;i < n && !mk;i ++)
          {
             memset(mark ,0 ,sizeof(mark));
             int l = edge[mst[i]].x ,r = edge[mst[i]].y;
             mark[l] = mark[r] = 1;
             ll = rr = 0;
             L[++ll] = l ,R[++rr] = r;    
             DFS1(l) ,DFS2(r);
             for(int j = 1 ;j <= ll && !mk;j ++)
             {
                for(int k = 1 ;k <= rr && !mk ;k ++)
                {
                   if(L[j] == edge[mst[i]].x && R[k] == edge[mst[i]].y || L[j] == edge[mst[i]].y && R[k] == edge[mst[i]].x)
                   continue;
                   if(map[L[j]][R[k]] == edge[mst[i]].c) mk = 1;
                }
             }
          }
          mk ? printf("Not Unique! "): printf("%d " ,Ans);
       }
       return 0;
    }
             
          
       
       
       
       
       
       




       
       
       
       






















     
       















  • 相关阅读:
    sql2000如何完美压缩.mdf文件
    SQL Server读懂语句运行的统计信息 SET STATISTICS TIME IO PROFILE ON
    Sql Server性能优化辅助指标SET STATISTICS TIME ON和SET STATISTICS IO ON
    理解性能的奥秘——应用程序中慢,SSMS中快(6)——SQL Server如何编译动态SQL
    理解性能的奥秘——应用程序中慢,SSMS中快(5)——案例:如何应对参数嗅探
    理解性能的奥秘——应用程序中慢,SSMS中快(4)——收集解决参数嗅探问题的信息
    理解性能的奥秘——应用程序中慢,SSMS中快(3)——不总是参数嗅探的错
    理解性能的奥秘——应用程序中慢,SSMS中快(2)——SQL Server如何编译存储过程
    巧用Map缓存提升"翻译"速度
    pt-archiver配置自动归档
  • 原文地址:https://www.cnblogs.com/csnd/p/12062604.html
Copyright © 2020-2023  润新知