2 glibc: gcc*: glibc uefi*: gcc*: raid_util*: uefi gpu_driver*: uefi opencl_sdk: gpu_drivergcc
Case 1: 1 Case 2: 2
链接:http://acm.hdu.edu.cn/showproblem.php?pid=5098
参考的博客:http://www.cnblogs.com/naturepengchen/articles/4069796.html
题意:
第一行 案例数。 然后每个案例用空行隔开。
每个案例都有若干行 ,第一个单词表示一个软件,如果名字后面有*号,代表安装这个软件需要重启。 多个软件可以同时 一次重启 安装。然后冒号后面 表示安装这个软件需要先安装的软件。
做法:
有两种做法,不过都需要先建图。用get函数来把字符串变成编号。 id 表示冒号前的软件,fu表示冒号后面的软件。要把 id 存入 vector son[fu], 就像树一样存。然后把 id的入度++;
第一种做法,拓扑排序。把入度为0的 且不需要重启的 存入q1队列,然后把 入度为0 的需要重启的存入 q2 队列。然后每次先把q1 队列里的 儿子们的入度都--, 如果某个儿子入度成了0,那么就代表这个儿子的父亲都已经安装好了,就是可以安装了,如果他需要重启,就入q2, 不需要入q1。 然后q1空了之后,就表示可以安装的,且不需要重启的都已经安装好了。然后安装q2队列了,把q2 队列 全放到q1就行了,然后重启次数++,表示一次重启,然后把他们都安装完了。
这种做法感觉像模拟一样,就是不断把入度0的处理掉。
第二种做法,记忆化搜索。dp[i]表示安装第i个软件需要多少步。然后dfs所有入度为0的,搜所有儿子,搜最大路径权值和。需要重启的权值为1,不需要权值为0。
代码:
第一种做法:
#include <stdio.h> #include <stdlib.h> #include <string.h> #include <limits.h> #include <malloc.h> #include <ctype.h> #include <math.h> #include <string> #include <iostream> #include <algorithm> using namespace std; #include <stack> #include <queue> #include <vector> #include <deque> #include <set> #include <map> #include <sstream> #define INF 999999999 #define eps 0.00001 #define LL __int64d #define pi acos(-1.0) map<string ,int> my; int reb[2010]; int du[2010];//入度 int dp[2010];//每个点下去最小步数 vector<int> son[2010]; int cnt; int get(string na) { if(my.count(na)==0) { my[na]=cnt; return cnt++; } else return my[na]; } int deal() { queue <int > q1,q2;//不需要重启 需要重启 for(int i=0;i<cnt;i++) { if(du[i]==0) { if(reb[i]==0) q1.push(i); else q2.push(i); } } int ans=0; while(!q1.empty()||!q2.empty()) { while(!q1.empty()) { int num=q1.front(); q1.pop(); for(int i=0;i<son[num].size();i++) { du[son[num][i]]--; if(du[son[num][i]]==0) { if(reb[son[num][i]]==0) q1.push(son[num][i]);//不需要重启的 都可以安装掉 else q2.push(son[num][i]); } } } if(!q2.empty()) ans++; while(!q2.empty()) { int num=q2.front(); q2.pop(); q1.push(num); } } return ans; } int main() { int t; int cas=1; string str; scanf("%d%*c",&t); getline(cin,str); while(t--) { my.clear(); cnt=0; memset(reb,0,sizeof reb); memset(du,0,sizeof du); for(int i=0;i<2000;i++) son[i].clear(); while(getline(cin,str)) { if(str.size()==0) break; stringstream sss; sss<<str; sss>>str; int mao=str.find(':'); int id; if(str[mao-1]=='*') id=get(str.substr(0,mao-1)); else id=get(str.substr(0,mao)); if(str[mao-1]=='*') reb[id]=1; while(sss>>str) { du[id]++; son[get(str)].push_back(id); } } cout<<"Case "<<cas++<<": "<<deal()<<endl; } return 0; }
第二种做法:
#include <stdio.h> #include <stdlib.h> #include <string.h> #include <limits.h> #include <malloc.h> #include <ctype.h> #include <math.h> #include <string> #include <iostream> #include <algorithm> using namespace std; #include <stack> #include <queue> #include <vector> #include <deque> #include <set> #include <map> #include <sstream> #define INF 999999999 #define eps 0.00001 #define LL __int64d #define pi acos(-1.0) map<string ,int> my; int reb[2010]; int du[2010];//入度 int dp[2010];//每个点下去最小步数 vector<int> son[2010]; int cnt; int get(string na) { if(my.count(na)==0) { my[na]=cnt; return cnt++; } else return my[na]; } int dfs(int id) { if(dp[id]!=-1) return dp[id]; int ans=reb[id]; for(int i=0;i<son[id].size();i++) { dfs(son[id][i]); ans=max(dp[son[id][i]]+reb[id],ans); } return dp[id]=ans; } int main() { int t; int cas=1; string str; scanf("%d%*c",&t); getline(cin,str); while(t--) { my.clear(); cnt=0; memset(reb,0,sizeof reb); memset(du,0,sizeof du); memset(dp,-1,sizeof dp); for(int i=0;i<2000;i++) son[i].clear(); while(getline(cin,str)) { if(str.size()==0) break; stringstream sss; sss<<str; sss>>str; int mao=str.find(':'); int id; if(str[mao-1]=='*') id=get(str.substr(0,mao-1)); else id=get(str.substr(0,mao)); if(str[mao-1]=='*') reb[id]=1; while(sss>>str) { du[id]++; //父亲先 son[get(str)].push_back(id); //cout<<str<<endl; } //cout<<str[mao]<<endl; //cout<<"id"<<id<<endl; } int ans=0; for(int i=0;i<cnt;i++) { if(du[i]==0) ans=max(ans,dfs(i)); } cout<<"Case "<<cas++<<": "<<ans<<endl; } return 0; }
hdu 5098 Smart Software Installer 拓扑排序or记忆化搜索
原文地址:http://blog.csdn.net/u013532224/article/details/45566625