Kingdoms

来源:互联网 发布:暖气管道钥匙 淘宝 编辑:程序博客网 时间:2024/05/22 14:52

Kingdoms

problem

题意:

有编号1..n的国家,之间以有向边连接,边的信息表示了一个国家对另一个国家的负债和债权情况。现在寻找资不抵债(破产)的国家,将其从图中抹去,这样它的负债和债权也被一并抹去。问,重复进行上述操作后有哪些国家可能是最终剩下的那一个。若有,则按它们编号的升序输出;若无,则输出0。

思路:

采用一种枚举的思路,用dfs枚举破产国家的各种组合,状态就用二十位的二进制位来表示:1表示破产,0表示正常。
具体实现方式见代码。现在用文字简单阐述一下算法过程。
采用位运算,直接将一个32位整形数作为保存状态的容器,对它的每一位进行枚举,做上标记(即按位或上一个1);用一个元素数量不少于 220 的布尔型数组保存已经讨论过的状态。每次枚举时检查枚举出的状态是否已经讨论过,若没有讨论过再进行判断,看最新枚举出的国家是否会破产,若破产,则记录下来,递归进入下一层,如此循环,直到递归状态为“已经找出了n-1个破产国家“。这时,将这个仅剩的国家放入一个vector。至此,就完成了寻找最后可以幸存的国家的工作。dfs确保每种情况都可以枚举出来,我们只需在dfs结束后检查vector的元素数量就可以得到答案:存在元素就排序输出,不存在则输出0。

#include <iostream>#include <cstdio>#include <algorithm>#include <vector>#include <cstring>#include <queue>using namespace std;const int maxn = 1048586;int n;bool bankruptcyStatus[maxn];int g[21][21];vector<int> res;void init(){    res.clear();    memset(bankruptcyStatus, false, sizeof(bankruptcyStatus));}/*函数参数 *state:它的二进制形式表示破产国家列表 *num:表示已经破产的国家数 */void dfs(int state, int num){    bankruptcyStatus[state] = true;    if(num == n - 1){        for(int i = 0; i < n; i++)            if(!(state & (1<<i)))               res.push_back(i+1);    }    for(int i = 0; i < n; i++){        // 引入bankruptcyStatus数组防止从多种路径到达已经计算过的同一种状态,达到剪枝的目的        if(!(state&(1<<i)) && !bankruptcyStatus[state|(1<<i)]){            int d = 0;            for(int j = 0; j < n; j++){                if(!(state&(1<<j)))                    d += g[i][j];            }            if(d > 0)                dfs(state|(1<<i), num+1);        }    }}int main(){#ifdef TESTfreopen("test.txt", "r", stdin);#endif // TEST    cin >> n;    while(cin >> n){        init();        for(int i = 0; i <n; i++){            for(int j = 0; j < n; j++){                scanf("%d", &g[i][j]);            }        }        dfs(0,0);        if(!res.size())            printf("0\n");        else{            sort(res.begin(), res.end());            for(int i = 0; i < res.size(); i++)                printf("%d%c", res[i], " \n"[i==res.size()-1]);        }    }    return 0;}
原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 玩手机麻将老输怎么办 打四川麻将老输怎么办 网上打麻将老输怎么办 手机打麻将老输怎么办 近来打麻将老输怎么办 最近手气不好老输钱怎么办 头被风吹了头痛怎么办 打麻将老输怎么办转运 外出时家里的花怎么办 放假了家里的花怎么办 老是怀疑老婆有外遇怎么办 老婆出轨我该怎么办呢 老公爱爱时间短怎么办 老婆离家出走了怎么办离婚呢 4g网络变成h了怎么办 打麻药伤到神经怎么办 40多岁乳房下垂怎么办 手冻了怎么办 小妙招 脸过敏好了还红怎么办 脸过过敏红肿痒怎么办 腰间盘突出压迫神经腿麻怎么办 腰椎盘突出脚麻怎么办 水泡破了化脓了怎么办 泰迪口臭很严重怎么办 狗狗的嘴巴好臭怎么办 2岁宝宝有口臭怎么办 2岁半宝宝口臭怎么办 胃热引起的口臭怎么办 脑梗右手不能动怎么办 脑梗右手不灵活怎么办 冒冷汗头晕想吐怎么办 脸中风嘴歪了怎么办 耳朵里疱疹破了怎么办 吃了变质的米饭怎么办 吃了变质的蛋糕怎么办 吃了变质的饭怎么办 颈椎病犯了头晕恶心怎么办 感冒引起的耳朵疼怎么办 感冒了左耳朵疼怎么办 受风引起的面瘫怎么办 两边的脸不一样大怎么办