System Dependencies UVA - 506 安装组件,细节模拟,递归,有dfs的感觉

题目链接

题目大意:

软件组件之间可能会有依赖关系,例如,TELNET和FTP都依赖于TCP/IP。你的任务是模拟安装和卸载软件组件的过程。首先是一些DEPEND指令,说明软件之间的依赖关系(保证不存在循环依赖),然后是一些INSTALL、REMOVE和LIST指令,如表6-1所示。
表6-1 指令说明
指令说明:

DEPEND item1 item2[item3 …] item1依赖组件item2, item3, …
INSTALL item1安装item1和它的依赖(已安装过的不用重新安装)
REMOVE item1卸载item1和它的依赖(如果某组件还被其他显式安装的组件所依赖,则不能卸载这个组件)
LIST卸载item1和它的依赖(如果某组件还被其他显式安装的组件所依赖,则不能卸载这个组件)

 

在INSTALL指令中提到的组件称为显式安装,这些组件必须用REMOVE指令显式删除。同样地,被这些显式安装组件所直接或间接依赖的其他组件也不能在REMOVE指令中删除。每行指令包含不超过80个字符,所有组件名称都是大小写敏感的。指令名称均为大写字母。

分析:

题意让我理解了半天,显式安装便是直接INSTALL安装上的组件,而隐式安装为因为依赖关系被安装上的组件。

这样一想,依赖关系就有点像拓扑了,可以按照拓扑的思想走。

我用了一个

map<string,pair<vector<string>,vector<string>>> map1;//first 依赖 second 被依赖

来记录依赖和被依赖关系,然后递归安装卸载即可。但一定要注意显式安装和隐式安装的情况,会决定题目的输出。

#include <bits/stdc++.h>
using namespace std;
const int maxn = 100000;
//first 依赖 second 被依赖
map<string,pair<vector<string>,vector<string>>> map1;
vector<string> installed;
map<string,int> statues;

bool is_needed(const string &str) {
    auto vec = map1[str].second;
    for (const auto &i : vec) {
        if(statues[i]) return true;
    }
    return false;
}

void Install(string str, bool flag) {
    if(!statues[str]) {
        auto vec = map1[str].first;
        for (const auto &i : vec)
            Install(i,false);
        if(flag) statues[str] = 1;
        else statues[str] = 2;
        installed.push_back(str);
        cout << "   Installing " << str << endl;
    }
}

void Remove(string str, bool flag) {
    if((flag || statues[str]==2) && !is_needed(str)){
        cout << "   Removing " << str << endl;
        statues[str] = 0;
        auto vec = map1[str].first;
        auto it = find(installed.begin(), installed.end(), str);
        installed.erase(it);
        for(const auto &i : vec)
            Remove(i,false);
    }
}

int main() {
    freopen("i.txt","r",stdin);
    freopen("o.txt","w",stdout);
    string str;
    while(getline(cin,str)) {
        cout << str << endl;
        if(str=="END") break;
        stringstream s(str);
        string temp,t[maxn];
        int cnt = 0;
        while(s>>temp)
            t[cnt++] = temp;
        if(t[0]=="DEPEND") {
            for(int i = 2; i < cnt; i++) {
                map1[t[1]].first.push_back(t[i]);
                map1[t[i]].second.push_back(t[1]);
            }
        }
        else if(t[0]=="INSTALL") {
            if(!statues[t[1]])
                Install(t[1],true);
            else
                cout << "   " << t[1] << " is already installed." << endl;
        }
        else if(t[0]=="REMOVE") {
            if(!statues[t[1]])
                cout << "   " << t[1] << " is not installed." << endl;
            else {
                if(is_needed(t[1]))
                    cout << "   " << t[1] << " is still is_needed." << endl;
                else Remove(t[1],true);
            }
        }
        else {
            for (const auto &i : installed)
                cout << "   " << i << endl;
        }
    }
}

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值