UVA506 System Dependencies(模拟)

题目链接:

https://vjudge.net/problem/31990/origin


题目大意:

模拟安装软件,分显式好隐式安装两种情况。安装一个软件的时候,指明安装的就是显式安装。
比如:

INSTALL A

这里A是显示安装,如果A必须要B和C软件的支持的话,顺便安装上B和C,这里B和C就是隐式安装上的。

然后是删除软件,删除的时候以递归的形式删除,先删除指明安装的软件,然后删除这个软件的支持软件,但是如果支持软件是显式安装上的话,就不删除了。

INSTALL B
INSTALL A
REMOVE A

这里的B就不会被删除,安装A时同时安装的C会被删除掉。此外如果A的支持软件是另一个软件的支持软件的话,也不会被删除掉。


解题过程:

题目本身不难,有是一个复杂的模拟题,书上给了些提示和代码,对比着,写出来不难。
需要映射下软件的名字,这里用到了之前 UVA-12096 里面的映射方法。


题目分析:

先把字符串名称用MAP映射成整数,容易处理些。
安装和删除的函数,注意递归处理。
把depend的输入分离的时候使用stringstream处理。

题目不难,不过用到了好多有用的方法,这里Mark下。


AC代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
#include<bits/stdc++.h>
using namespace std;

const int MAX = 112345;

map<string, int> nameList;
vector<string> getName, nameTable;
string str;
vector<int> depend1[MAX], depend2[MAX];
int status[MAX];
string blank = " ";

int ID(string name)
{
if (nameList.count(name))
return nameList[name];

getName.push_back(name);
return nameList[name] = getName.size()-1;
}

void depend()
{
stringstream ss;
string item_name;
int item1, item2;
ss << str;
ss >> item_name;

ss >> item_name;
item1 = ID(item_name);

while (ss >> item_name)
{
item2 = ID(item_name);
depend1[item1].push_back(item2);
depend2[item2].push_back(item1);
}
}

void install(int item, bool topLevel)
{
if (!status[item])
{
for (int i = 0; i < depend1[item].size(); i++)
install(depend1[item][i], false);

string item_name = getName[item];
cout << blank << "Installing " << item_name << endl;
nameTable.push_back(item_name);
status[item] = topLevel? 1:2;
}
else if (topLevel)
cout << blank << getName[item] << " is already installed." << endl;
}

void list_()
{
for (int i = 0; i < nameTable.size(); i++)
cout << blank << nameTable[i] << endl;
}

bool needed(int item)
{
for (int i = 0; i < depend2[item].size(); i++)
if (status[depend2[item][i]])
return true;
return false;
}

void remove_(int item, bool topLevel)
{
string item_name = getName[item];
if (status[item] == 0 && topLevel)
{
cout << blank << item_name << " is not installed." << endl;
return;
}

if (!needed(item) && (status[item] == 2 || topLevel))
{
status[item] = 0;
for (int i = 0; i < nameTable.size(); i++)
{
if (nameTable[i] == item_name)
{
nameTable.erase(nameTable.begin()+i);
break;
}
}
cout << blank << "Removing " << item_name << endl;

for (int i = 0; i < depend1[item].size(); i++)
remove_(depend1[item][i], false);
}
else if (topLevel)
cout << blank << item_name << " is still needed." << endl;
}

int main()
{
// freopen("in","r",stdin);
while(getline(cin, str))
{
cout << str << endl;
if (str[0] == 'D')
{
depend();
}

if (str[0] == 'I')
{
stringstream ss;
ss << str;
string item_name;
ss >> item_name;
ss >> item_name;

int item = ID(item_name);

install(item, true);
}

if (str[0] == 'E')
{
break;
}

if (str[0] == 'R')
{
stringstream ss;
ss << str;
string item_name;
ss >> item_name;
ss >> item_name;

int item = ID(item_name);

remove_(item, true);
}

if (str[0] == 'L')
{
list_();
}
}
}