求助大佬,uDebug 上的 Case 都通过了
查看原帖
求助大佬,uDebug 上的 Case 都通过了
369937
w568w楼主2021/2/7 12:32

uDebug 上的两个样例都通过了,题解也合拍过了...
但是一直 WA ,不清楚是哪里出问题了QAQ 感觉就是一道普通的 IDDFS 啊...

#include <bits/stdc++.h>
#define _for(A, B, C) for(int A = (B);A < (C);A++)
using namespace std;

int n;
//输入的图。输入后就不再改变,只用degree[]代表打开状态
bool G[15][15];
//每个节点的度数,-1表示该节点已被打开
int degree[15];
#define OPENED_DEGREE -1
//最大深度
int maxDepth;


#define NO_SEARCHED 0

//节点的编号,用于计算连通块
int idx[15];

//遍历图,标记连通个数,并在遇到回环时返回false
bool topo(int lastOne, int startNode, int id) {
    idx[startNode] = -id;
    if (degree[startNode] == 0)return true;
    bool ok = true;
    _for(i, 0, n) {
        if (G[startNode][i] && degree[i] > 0) {
            if (idx[i] == -id && i != lastOne)ok = false;
            if (idx[i] == NO_SEARCHED && !topo(startNode, i, id))ok = false;
        }
    }
    idx[startNode] = id;
    return ok;
}

inline bool legal() {
    //已打开的环的数目(包括原先是单个环,但是已经打开的情况)
    int openCnt = 0;
    _for(i, 0, n) {
        if (degree[i] == OPENED_DEGREE)openCnt++;
        if (degree[i] > 2)return false;
    }

    memset(idx, NO_SEARCHED, sizeof(idx));

    //连通块个数
    int cnt = 0;
    _for(i, 0, n) {
        if (idx[i] == NO_SEARCHED) {
            if (!topo(-1, i, ++cnt))return false;
        }
    }

    //满足该条件才能全部连接上
    return (openCnt << 1) + 1 >= cnt;
}

//第cur层,从from开始枚举
bool IDDFS(int from, int cur) {
    if (cur == maxDepth) {
        //判断是否合法
        return legal();
    } else {
        int oriDegree[15];
        _for(i, from, n) {
            if (degree[i] == OPENED_DEGREE)continue;
            //保存之前的degree
            memcpy(oriDegree, degree, sizeof(degree));
            //标记为已打开
            degree[i] = OPENED_DEGREE;
            //更新其他degree
            _for(j, 0, n) {

                if (degree[j] > 0 && G[j][i]) {
                    degree[j]--;
                }
            }

            if (IDDFS(i + 1, cur + 1))return true;
            //还原之前的degree
            memcpy(degree, oriDegree, sizeof(degree));
        }
    }
    return false;
}

int solve() {
    for (maxDepth = 0; maxDepth <= n; ++maxDepth) {
        if (IDDFS(0, 0)) {
            return maxDepth;
        }
    }
    return -1;
}

int main() {
//    freopen("in.txt", "r", stdin);
    int k = 0;
    while (cin >> n && n) {
        memset(G, false, sizeof(G));
        memset(degree, 0, sizeof(degree));
        int a, b;
        while (cin >> a && cin >> b && a > 0 && b > 0) {
            a--, b--;
            if (G[a][b] || G[b][a])continue;
            G[a][b] = G[b][a] = true;
            degree[a]++;
            degree[b]++;
        }
        cout << "Set " << ++k << ": Minimum links to open is " << solve() << endl;
    }
    return 0;
}
2021/2/7 12:32
加载中...