UVA

/*
  分析可见小白书 P174,我的代码中也有部分的分析和解释
  
  收获:
  1. vector中,remove 和 erase 联合,用来删除指定的元素
  
  某个blog上有言简意赅的一个用法的举例说明 ( 来自: http://www.cnblogs.com/warmbeast/p/5325874.html):
  
  vector<int> v;      
  v.erase(remove(v.begin(),v.end(),99),v.end());//真的删除所有等于99的元素
  
  此外,还要注意的是,unique 和 erase 也有类似的用法,因为 unique 的去重,也不是真正的去重,而是将重复元素移动到 vector 的后面
  ( 这个要点,我在之前做题时也曾经遇到过,可看此链接:   http://blog.csdn.net/mofushaohua_ln/article/details/77795409 )
  
*/


/*
  查阅过的网址汇总:
  1. 关于 remove 和 erase:
  http://www.cnblogs.com/warmbeast/p/5325874.html
  http://lib.csdn.net/article/cplusplus/29700
  http://blog.csdn.net/ozwarld/article/details/7761519
  http://blog.csdn.net/yockie/article/details/7859330
  
  2. sstream 用于 string 类的分离:
  http://blog.csdn.net/jibancanyang/article/details/43400009
  http://blog.csdn.net/xiaogugood/article/details/21447431
  
*/


#include <iostream>
#include <cstring>
#include <string>
#include <map>
#include <vector>
#include <sstream>
#include <algorithm> // remove()函数的头文件 
#define rep(i, n) for ( int i = 0; i < (n); i++ )
using namespace std;

const int N = 1e4;
int cnt = 0;
int status[N]; // 0 表示未安装, 1 表示显式安装, 2 表示隐式安装 
string name[N];
map<string, int> name_id;
vector<int> depend[N], depend2[N]; // depend[x] 和 depend2[x] 分别表示,x所依赖的组件,和依赖于x的组件列表 
vector<int> installed; // 按照安装顺序,保存安装的所有组件 

int ID ( const string& str)
{
	if ( !name_id.count(str) )
	{
		name[++cnt] = str;
		name_id[str] = cnt;
	}
	return name_id[str];
}

bool needed (int item)
{
	rep( i, (int)depend2[item].size() )
	if ( status[depend2[item][i]] ) return true;
	return false;
}

/*
  type 表示安装类型,表明当前是显式安装,还是隐式安装
  显式和隐式安装的定义,是我们人为去规定的,可以这么描述:
  显式就是,INSTALL 指令直接指定安装的文件
  隐式就是,非 INSTALL 指令直接指定安装的文件,而是在安装别的文件时,可能由于需要这个文件,所以需要隐式先安装它 
  
  两者的区别在于:
  显式安装的组件,必须用 REMOVE 指令显式删除
  被显式安装组件,所直接或间接依赖,进而被隐式安装的其他组件,不能在 REMOVE 指令中删除 
*/ 
void install ( int item, bool type ) 
{
	if ( !status[item] ) //未安装才安装,不重复安装 
	{
		rep (i, (int)depend[item].size())
		install(depend[item][i], false);
		
		cout << "   Installing " << name[item] << endl;
		status[item] = type ? 1 : 2;
		installed.push_back(item);
	}
}

/*
   删除组件的前提: 
   如果要删除,首先肯定要满足,不可再有依赖它的组件
   还需要满足,要么是通过 REMOVE 删除,要么是安装时隐式安装 ( 因而,删除 REMOVE 指令要求删除的组件时,如果不再被任何组件依赖,就会和要删除的组件,一起被删除 )
   
   有个一定要小心的小细节:显式安装的,必须被显式删除 ,不能被隐式删除 
*/ 
void remove ( int item, bool type )
{
	if ( ( type || status[item] == 2 ) && !needed(item) )
	{
		status[item] = 0;
		installed.erase( remove (installed.begin(), installed.end(), item), installed.end() );
		cout << "   Removing " << name[item] << endl;
		
		rep( i, (int)depend[item].size() )
		remove( depend[item][i], false );
	}
}

// 按照安装顺序输出
void list ()
{
	rep ( i, (int)installed.size() )
	cout << "   " << name[installed[i]] << endl;
}

void solve ()
{
	string str, cmd; // cmd: command
	string s1, s2;
	memset ( status, 0, sizeof(status) );
	
	while ( getline(cin, str) )
	{
		cout << str << endl;
		stringstream ss (str);
		ss >> cmd;
		
		if ( cmd[0] == 'E' ) break;
		if ( cmd[0] == 'L') list();
		else
		{
			ss >> s1;
			int i1 = ID (s1);
			
			if ( cmd[0] == 'D' )
			{
				while (ss >> s2)
				{
					int i2 = ID (s2);
					depend[i1].push_back(i2);
					depend2[i2].push_back(i1);
				}
			}
			
			else if ( cmd[0] == 'I' )
			{
				if ( status[i1] ) cout << "   " << s1 << " is already installed." << endl;
				else install (i1, true);
			}
			
			else
			{
				if ( !status[i1] ) cout << "   " << s1 << " is not installed." << endl;
				else if ( needed(i1) ) cout << "   " << s1 << " is still needed." << endl;
				else remove (i1, true);
			}
		}
	}
}

int main ()
{
	solve();
	return 0;
}



原文地址:https://www.cnblogs.com/mofushaohua/p/7789387.html