Description
Components of computer systems often have dependencies—other components that must be installed before they will function properly. These dependencies are frequently shared by multiple components. For example, both the TELNET client program and the FTP client program require that the TCP/IP networking software be installed before they can operate. If you install TCP/IP and the TELNET client program, and later decide to add the FTP client program, you do not need to reinstall TCP/IP.
For some components it would not be a problem if the components on which they depended were reinstalled; it would just waste some resources. But for others, like TCP/IP, some component configuration may be destroyed if the component was reinstalled.
It is useful to be able to remove components that are no longer needed. When this is done, components that only support the removed component may also be removed, freeing up disk space, memory, and other resources. But a supporting component, not explicitly installed, may be removed only if all components which depend on it are also removed. For example, removing the FTP client program and TCP/IP would mean the TELNET client program, which was not removed, would no longer operate. Likewise, removing TCP/IP by itself would cause the failure of both the TELNET and the FTP client programs. Also if we installed TCP/IP to support our own development, then installed the TELNET client (which depends on TCP/IP) and then still later removed the TELNET client, we would not want TCP/IP to be removed.
We want a program to automate the process of adding and removing components. To do this we will maintain a record of installed components and component dependencies. A component can be installed explicitly in response to a command (unless it is already installed), or implicitly if it is needed for some other component being installed. Likewise, a component, not explicitly installed, can be explicitly removed in response to a command (if it is not needed to support other components) or implicitly removed if it is no longer needed to support another component. Installing an already implicitly-installed component won’t make that component become explicity installed.
Input
The input fifile contains several test cases, each of them as described below.
The input will contain a sequence of commands (as described below), each on a separate line containing no more than eighty characters. Item names are case sensitive, and each is no longer than ten characters. The command names (DEPEND, INSTALL, REMOVE and LIST) always appear in uppercase starting in column one, and item names are separated from the command name and each other by one or more spaces. All appropriate DEPEND commands will appear before the occurrence of any INSTALL command that uses them. There will be no circular dependencies. The end of the input is marked by a line containing only the word END.
Output
For each test case, the output must follow the description below.
Echo each line of input. Follow each echoed INSTALL or REMOVE line with the actions taken in response, making certain that the actions are given in the proper order. Also identify exceptional conditions (see Sample Output, below, for examples of all cases). For the LIST command, display the names of the currently installed components in the installation order. No output, except the echo, is produced for a DEPEND command or the line containing END. There will be at most one dependency list per item.
Samples
Input
DEPEND TELNET TCPIP NETCARD
DEPEND TCPIP NETCARD
DEPEND DNS TCPIP NETCARD
DEPEND BROWSER TCPIP HTML
INSTALL NETCARD
INSTALL TELNET
INSTALL foo
REMOVE NETCARD
INSTALL BROWSER
INSTALL DNS
LIST
REMOVE TELNET
REMOVE NETCARD
REMOVE DNS
REMOVE NETCARD
INSTALL NETCARD
REMOVE TCPIP
REMOVE BROWSER
REMOVE TCPIP
END
Output
DEPEND TELNET TCPIP NETCARD
DEPEND TCPIP NETCARD
DEPEND DNS TCPIP NETCARD
DEPEND BROWSER TCPIP HTML
INSTALL NETCARD
Installing NETCARD
INSTALL TELNET
Installing TCPIP
Installing TELNET
INSTALL foo
Installing foo
REMOVE NETCARD
NETCARD is still needed.
INSTALL BROWSER
Installing HTML
Installing BROWSER
INSTALL DNS
Installing DNS
LIST
NETCARD
TCPIP
TELNET
foo
HTML
BROWSER
DNS
REMOVE TELNET
Removing TELNET
REMOVE NETCARD
NETCARD is still needed.
REMOVE DNS
Removing DNS
REMOVE NETCARD
NETCARD is still needed.
INSTALL NETCARD
NETCARD is already installed.
REMOVE TCPIP
TCPIP is still needed.
REMOVE BROWSER
Removing BROWSER
Removing HTML
Removing TCPIP
REMOVE TCPIP
TCPIP is not installed.
END
Source
UVA 506
输入:首先输入各组件间的依赖关系,然后输入个个命令,END为结束命令;
输出:先输出命令,然后按要求输出(要求如下表格所示)
指令说明:
指令 | 说明 |
---|---|
DEPEND t1 t2 t3 … | t1的安装依赖t2 t2 … |
INSTALL t1 | 安装t1和它的依赖(已安装过的无需重复安装) |
REMOVE t1 | 卸载t1和他的依赖(如果该组件被其他显式安装的组件依赖(即有组件需要t1的支持),则不能删除该组件) |
LIST | 输出所有已安装组件(按安装顺序输出) |
附加说明:
①A依赖B — A必须在B存在的条件下使用
②若组件以被依赖的形式安装,则其状态为1
Code:
#include<bits/stdc++.h>
using namespace std;
const int N=1e4 + 10;
vector<int> depend[N],depended[N];
map<string,int> m;
string name[N];
int status[N],len;
vector<int> in;
void work(string s) {
if(!m.count(s)) {
m[s]=len;
name[len++]=s;
}
}
void install(int id,bool top) {
for(int i=0; i<depend[id].size(); i++)
if(!status[depend[id][i]]) install(depend[id][i],0);
cout << " Installing " << name[id] <<endl;
status[id]=top ? 1 : 2;
//cout<<"name="<<name[id]<<" 状态:"<< status[id]<<endl;
in.push_back(id);
}
bool needed(int id) {
for(int i=0; i<depended[id].size(); i++)
if(status[depended[id][i]]) return 1;
return 0;
}
void remove(int id,bool top) {
if((top || status[id]==2) && !needed(id)) {
status[id]=0;
cout << " Removing " << name[id] <<endl;
in.erase(remove(in.begin(),in.end(),id),in.end());
//vector中的remove的作用是将等于value的元素放到vector的尾部,但并不减少vector的size。
for(int i = 0; i<depend[id].size() ; i++)
remove(depend[id][i], 0);
}
}
int main() {
string s;
m.clear();
while(getline(cin,s) ) {
stringstream ss(s);
cout<<s<<endl;
if(!s.compare("END")) break;
ss>>s;
if(s=="DEPEND") {
ss>>s;
work(s);
string a;
while(ss>>a) {
work(a);
depend[m[s]].push_back(m[a]);
depended[m[a]].push_back(m[s]);
}
} else if(s=="INSTALL") {
ss>>s;
work(s);
if(!status[m[s]]) install(m[s],1);
else cout<<" "<<name[m[s]]<<" is already installed."<<endl;
} else if(s=="REMOVE") {
ss>>s;
if(!status[m[s]]) cout<<" "<<s<<" is not installed."<<endl;
else {
if(needed(m[s])) cout<<" "<<name[m[s]]<<" is still needed."<<endl;
else remove(m[s],1);
}
} else if(s=="LIST") {
for(int i=0; i<in.size(); i++) cout<<" "<<name[in[i]]<<endl;
}
}
return 0;
}
/*
DEPEND TELNET TCPIP NETCARD
DEPEND TCPIP X
DEPEND DNS TCPIP NETCARD
DEPEND BROWSER TCPIP HTML
INSTALL TELNET
INSTALL foo
REMOVE NETCARD
INSTALL BROWSER
INSTALL DNS
LIST
REMOVE TELNET
REMOVE NETCARD
REMOVE DNS
REMOVE NETCARD
INSTALL NETCARD
REMOVE TCPIP
REMOVE BROWSER
REMOVE TCPIP
END
*/
参考紫书176页内容
电子版链接.(与书上内容基本一致)