zoukankan      html  css  js  c++  java
  • 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;
    }
             
          
       
       
       
       
       
       




       
       
       
       






















     
       















  • 相关阅读:
    DOM 高级编程笔记
    什么是目标管理?什么叫smart原则?
    HTML文档中小meta的大作用
    《javascript权威指南》基础笔记 重要
    应聘时最漂亮的回答 转
    JS在IE和Firefox之间的区别
    apply与call的用法及区别
    谈谈Ajax跨域
    《高性能网站建设指南》、《高性能网站建设进阶指南》笔记
    HTTP协议状态码详解(HTTP Status Code)
  • 原文地址:https://www.cnblogs.com/csnd/p/12062604.html
Copyright © 2011-2022 走看看