并查集+回溯---七段码

package top.zbawq.lanqiao11A;

/*
    主要实现两种功能:合并、查询
    初始化
        for (int i = 1; i <= n; ++i)
            fa[i] = i; //指向其自身
    查询
        int find(int x){
            if(fa[x] == x)
                return x;
            else
                return find(fa[x]);
        }
    合并
        inline void merge(int i, int j)
        {
            fa[find(i)] = find(j);
        }
 */
public class 并查集 {
    static int[] fa;
    static int[][] e;
    static int[] use;
    static int ans;
    // 查询   查找祖先节点
    public static int get(int cur){
        if(cur == fa[cur]) return cur;
        return get(fa[cur]);
    }
    //合并  把num1的祖先节点合并到num2的祖先节点上
    public static void merge(int num1,int num2){
        fa[get(num1)]=get(num2);
    }
    public static void init(int n){
        fa=new int[8];
        e=new int[8][8];
        use=new int[8];
        ans=0;
        for (int i = 1; i <= n; i++) {
            fa[i]=i;
        }
        //表示初始边集,唯一代表两者相邻
        e[1][2]=e[1][6]=1;
        e[2][1]=e[2][7]=e[2][3]=1;
        e[3][2]=e[3][4]=e[3][7]=1;
        e[4][3]=e[4][5]=1;
        e[5][4]=e[5][6]=e[5][7]=1;
        e[6][1]=e[6][5]=e[6][7]=1;
    }
    public static void dfs(int d){
        if(d>7) {
            for(int i=1;i<=7;i++)fa[i]=i;//初始化父亲集合
            for (int i = 1; i <= 7; i++) {
                for (int j = 1; j <= 7; j++) {
                    if (e[i][j] == 1 && use[i] == 1 && use[j] == 1) {
                        merge(get(i),get(j));
                    }
                }
            }
            int k = 0;
            //代表只有一个回路
            for (int i = 1; i <= 7; i++)
                // fa[i]==1代表只有一个根节点
                if (use[i] == 1 && fa[i] == i) k++;
            if (k == 1) ans++;//如果所有亮灯都属于同一个集合
            return;
        }
        use[d]=1;//打开d这个灯,继续开关下一个灯
        dfs(d+1);
        use[d]=0;//关闭d这个灯,继续开关下一个灯
        dfs(d+1);
    }
    public static void main(String[] args) {
        //初始化
        init(7);
        dfs(1);
        System.out.println(ans);
    }

}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值