#include <iostream>
#include <istream>
#include <sstream>
#include <vector>
#include <stack>
#include <list>
#include <map>
#include <set>
#include <deque>
#include <queue>
#include <cstring>
#include <unordered_map>
#include <unordered_set>
#include <algorithm>
#include <numeric>
#include <chrono>
#include <ctime>
#include <cmath>
#include <cctype>
#include <string>
#include <cstdio>
#include <iomanip>
#include <thread>
#include <mutex>
#include <condition_variable>
#include <functional>
#include <iterator>
using namespace std;
//安装列表
list<string> mlist;
//依赖表
unordered_map<string, vector<string> > head;
//显示安装表
unordered_set<string> show;
//反向依赖表
unordered_map<string, unordered_set<string>> rev;
//安装列表位置
unordered_map<string, list<string>::iterator > arr;
void Init() {
mlist.clear(); head.clear(); show.clear(); rev.clear(); arr.clear();
}
int GetStr(string& in,string &out, int &i) {
out = "";
while (i < in.size() && in[i] == ' ') ++i;
while (i < in.size() && in[i] != ' ')out += in[i++];
return i;
}
int HasStr(string& in) {
return arr.count(in);
}
void Install(string& in) {
vector<string>& a = head[in];
//安装依赖
for (int i = 0; i < a.size(); ++i) {
//没有循环依赖 不会死循环
if (!HasStr(a[i])) {
Install(a[i]);
}
rev[a[i]].insert(in);
}
arr[in] = mlist.insert(mlist.end(), in);
cout << " Installing " << in << endl;
}
void Remove(string& in) {
show.erase(in);
mlist.erase(arr[in]);
arr.erase(in);
cout << " Removing " << in << endl;
vector<string>& a = head[in];
for (int i = 0; i < a.size(); ++i) {
rev[a[i]].erase(in);
if(arr.count(a[i]) == 0 || show.count(a[i]) || rev[a[i]].size()) continue;
Remove(a[i]);
}
rev[in].clear();
}
void List() {
for (auto it = mlist.begin();it != mlist.end();it++)
cout << " " << *it << endl;
}
int main()
{
string in,item ,temp,item2;
while (getline(cin, in) && in != "END") {
int i = 0;
item = temp = "";
GetStr(in, item, i);
cout << in << endl;
if (item == "DEPEND") {
GetStr(in, item, i);
while (GetStr(in, item2, i) <= in.size() && !item2.empty())
head[item].emplace_back(item2);
}
else if (item == "INSTALL") {
GetStr(in, temp, i);
if(HasStr(temp))cout << " " << temp << " is already installed." << endl;
else {
Install(temp);
show.insert(temp);
}
}
else if (item == "REMOVE") {
GetStr(in, temp, i);
if (arr.count(temp) == 0)
cout << " " << temp << " is not installed." << endl;
else if (rev[temp].size())
cout << " " << temp << " is still needed." << endl;
else
Remove(temp);
}
else if (item == "LIST") {
List();
}
}
cout << in << endl;
return 0;
}
12-25
05-16
07-28
07-28