这个题目逻辑稍微复杂一点,关键在于remove操作,其他的操作紫书已经讲的比较明确了,对于电脑中的每个软件,设置了三种状态,第一种状态记为0,表示没有安装相应的软件,第二种状态记为1,表示该软件的安装是通过控制台的命令进行的,第三种状态记为2,表示这种软件是作为辅助选项在其他软件安装过程当中被安装的。同时写好函数isneeded表示当前的待删除的软件是否还被其他的软件需要,如果不需要的话,那么就删除当前的软件,同时递归的判断相应的被删除软件的辅助软件是否是隐式安装的,如果是隐式安装的同时又没有其他的软件需要该隐式安装的软件,那么就进行递归的删除。其他的操作就一目了然,具体实现见下面的代码:
#include<iostream>
#include<vector>
#include<string>
#include<set>
#include<stack>
#include<queue>
#include<map>
#include<algorithm>
#include<cmath>
#include<iomanip>
#include<cstring>
#include<sstream>
using namespace std;
int n, m;
vector<vector<int>> depend(100000,vector<int>());
vector<vector<int>> depended(100000,vector<int>());
map<string, int> str2in;
map<int, string> in2str;
vector<int> status(100000,0);
vector<string> installed;
bool isneeded(int index){
for (int i = 0; i < depended[index].size(); i++){
if (status[depended[index][i]]) return true;
}
return false;
}
int getId(string name){
if (str2in.find(name) == str2in.end()){
int size = str2in.size();
str2in[name] = size;
in2str[size] = name;
}
return str2in[name];
}
void setDepend(stringstream& is){
string first;
is >> first;
int first_id = getId(first);
string second;
while (is >> second){
int second_id = getId(second);
depend[first_id].push_back(second_id);
depended[second_id].push_back(first_id);
}
}
void install(string name,bool flag){
int name_id = getId(name);
if (status[name_id] != 0&&flag){
cout <<" "<< name << " is already installed." << endl;
return;
}
else if (status[name_id] != 0 && !flag) return;
else {
for (int i = 0; i < depend[name_id].size(); i++){
int index = depend[name_id][i];
string name2 = in2str[index];
if (status[index] == 0){
install(name2, false);
}
}
if (flag)
status[name_id] = 1;
else status[name_id] = 2;
installed.push_back(name);
cout << " Installing " << name << endl;;
}
}
void remove(string name,bool flag){
int index = str2in[name];
if ((flag || status[index]==2) && (!isneeded(index))){
cout << " Removing " << name << endl;
status[index] = 0;
installed.erase(find(installed.begin(),installed.end(),name));
for (int i = 0; i < depend[index].size(); i++){
string name2 = in2str[depend[index][i]];
remove(name2, false);
}
}
}
int main(){
string s;
while (getline(cin, s)){
cout << s << endl;
if (s == "END") break;
stringstream is(s);
string command;
is >> command;
if (command[0] == 'D'){
setDepend(is);
}
else if (command[0] == 'I'){
string name;
is >> name;
install(name, true);
}
else if (command[0] == 'R'){
string name;
is >> name;
int index = str2in[name];
if (status[index] == 0) cout << " " << name << " is not installed." << endl;
else if (isneeded(index)) cout << " " << name << " is still needed." << endl;
else{
remove(name, true);
}
}
else if (command[0] == 'L'){
for (int i = 0; i < installed.size(); i++){
cout <<" "<< installed[i] << endl;
}
}
}
//system("pause");
return 0;
}