• 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;
    }
             
          
       
       
       
       
       
       




       
       
       
       






















     
       















  • 相关阅读:
    Ocelot简易教程(二)之快速开始2
    jQuery编程小结
    用户界面的一些好的设计理念
    JQuery插件开发教程
    ASP.NET MVC IOC 之AutoFac攻略
    ASP.NET MVC IOC 之Ninject攻略
    ASP.NET MVC IOC之Unity攻略
    ASP.NET MVC之单元测试分分钟的事
    C#秘密武器之扩展方法
    让AutoMapper在你的项目里飞一会儿
  • 原文地址:https://www.cnblogs.com/csnd/p/12062603.html
Copyright © 2020-2023  润新知