zoukankan      html  css  js  c++  java
  • UVA506-System Dependencies(拓扑序)

    Problem UVA506-System Dependencies

    Accept:285  Submit:2824

    Time Limit: 3000 mSec

    Problem 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 file 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

     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.

     Sample 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
     
     

     Sample Ouput

    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 TCPIP
       Removing HTML
    REMOVE TCPIP
       TCPIP is not installed.
    END

    题解:一个比较麻烦的模拟,对于一个软件来说,有依赖和被依赖两种参数,因此用了depend,depend2两个vector将整个图用类似双链表的方式串了起来,这一步操作十分关键,有了双链表就可以方便地找到要删除的元素和要添加的元素。这个题还有一个比较麻烦的地方就是安装有显式和隐式两种,而显式安装的只能够被显式删除,隐式安装的都可以,为了区分这个,引入status数组,0表示未安装,1表示显式,2表示隐式,模拟的时候加一个判断就好,然后还要注意的是安装和删除均为递归操作,那么输出的语句应该放在哪里。其实这个问题很简单,安装时一定要先安装拓扑序中最靠前的软件,因此要递归到底再输出,删除就是翻着来,可以类比树的后序、先序遍历。

     1 #include <bits/stdc++.h>
     2 using namespace std;
     3 
     4 const int maxn = 10000+10;
     5 vector<int> depend[maxn],depend2[maxn];
     6 vector<int> installed;
     7 map<string,int> ID;
     8 string name[maxn];
     9 int cnt;
    10 int status[maxn];
    11 
    12 int find_ID(string &item){
    13     if(!ID.count(item)){
    14         ID[item] = cnt;
    15         name[cnt++] = item;
    16     }
    17     return ID[item];
    18 }
    19 
    20 bool needed(int id){
    21     for(int i = 0;i < depend2[id].size();i++){
    22         if(status[depend2[id][i]]) return true;
    23     }
    24     return false;
    25 }
    26 
    27 void List(){
    28     for(int i = 0;i < installed.size();i++){
    29         cout << "   " << name[installed[i]] << endl;
    30     }
    31 }
    32 
    33 void install(int id,bool toplevel){
    34     if(!status[id]){
    35         for(int i = 0;i < depend[id].size();i++){
    36             install(depend[id][i],false);
    37         }
    38         status[id] = toplevel ? 1 : 2;
    39         cout << "   Installing " << name[id] << endl;
    40         installed.push_back(id);
    41     }
    42 }
    43 
    44 void Remove(int id,bool toplevel){
    45     if((toplevel || status[id]==2) && !needed(id)){
    46         installed.erase(remove(installed.begin(),installed.end(),id),installed.end());
    47         cout << "   Removing " << name[id] << endl;
    48         status[id] = 0;
    49         for(int i = 0;i < depend[id].size();i++){
    50             Remove(depend[id][i],false);
    51         }
    52     }
    53 }
    54 
    55 int main()
    56 {
    57     //freopen("input.txt","r",stdin);
    58     cnt = 0;
    59     string ope;
    60     memset(status,0,sizeof(status));
    61     while(getline(cin,ope)){
    62         cout << ope << endl;
    63         stringstream ss(ope);
    64         ss >> ope;
    65         if(ope[0] == 'E') break;
    66         string item1,item2;
    67         if(ope[0] == 'L') List();
    68         else{
    69             ss >> item1;
    70             int id = find_ID(item1);
    71             if(ope[0] == 'D'){
    72                 while(ss >> item2){
    73                     int id2 = find_ID(item2);
    74                     depend[id].push_back(id2);
    75                     depend2[id2].push_back(id);
    76                 }
    77             }
    78             else if(ope[0] == 'I'){
    79                 if(status[id]) cout << "   " << item1 << " is already installed." << endl;
    80                 else install(id,true);
    81             }
    82             else{
    83                 if(!status[id]) cout << "   " << item1 << " is not installed." << endl;
    84                 else if(needed(id)) cout << "   " << item1 << " is still needed." << endl;
    85                 else Remove(id,true);
    86             }
    87         }
    88     }
    89     return 0;
    90 }
  • 相关阅读:
    魔术方法___toString()
    魔术方法__set()
    魔术方法__get()
    php面向对象之final关键字用法及实例
    php面向对象之什么是抽象类?及抽象类的作用
    php面向对象之对象克隆方法
    php面向对象之对象比较用法详解
    php面向对象之instanceof关键字的用法
    php表单怎么提交到数据库?
    php表单的验证详解
  • 原文地址:https://www.cnblogs.com/npugen/p/9520334.html
Copyright © 2011-2022 走看看