您的位置:首页 > 其它

Hdu 5098 Smart Software Installer【思维+拓扑排序】

2017-07-26 13:21 495 查看


Smart Software Installer

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)

Total Submission(s): 837    Accepted Submission(s): 270


Problem Description

The software installation is becoming more and more complex. An automatic tool is often useful to manage this process. An IT company is developing a system management utility to install a set of software packages automatically with the dependencies. They found
that reboot is often required to take effect after installing some software. A software package cannot be installed until all software packages it depends on are installed and take effect. 

In the beginning, they implemented a simple installation algorithm, but the system would reboot many times during the installation process. This will have a great impact on the user experience. After some study, they think that this process can be further optimized
by means of installing as much packages as possible before each reboot.

Now, could you please design and implement this algorithm for them to minimize the number of restart during the entire installation process?

 

Input

The first line is an integer n (1 <= n <= 100), which is the number of test cases. The second line is blank. The input of two test cases is separated by a blank line.

Each test case contains m (1 <= n <= 1000) continuous lines and each line is no longer than 1024 characters. Each line starts with a package name and a comma (:). If an asterisk (*) exists between the package name and the comma, the reboot operation is required
for this package. The remaining line is the other package names it depends on, separated by whitespace. Empty means that there is no dependency for this software. For example, “a: b” means package b is required to be installed before package a. Package names
consist of letters, digits and underscores, excluding other special symbols.

Assume all packages here need to be installed and all referenced packages will be listed in an individual line to define the reboot property. It should be noted that cyclic dependencies are not allowed in this problem.

 

Output

For each test case, you should output a line starting with “Case #: " (# is the No. of the test case, starting from 1) and containing the reboot count for this test case. (Refer to the sample format)

 

Sample Input

2

glibc:
gcc*: glibc

uefi*:
gcc*:
raid_util*: uefi
gpu_driver*: uefi
opencl_sdk: gpu_driver gcc

 

Sample Output

Case 1: 1
Case 2: 2

题目大意:

现在有一堆软件需要安装,打星号的软件是安装完需要重启电脑才能生效的软件,不打星号的软件是直接安装就能生效的软件。

当且仅当一个软件可以安装的条件是他所依赖的软件必须全部生效了才行。

问最少重启多少次电脑,能够将所有的软件都安装完毕。

思路:

我们肯定希望先进行安装不需要重启电脑的软件,那么我们每次安装软件的时候,先将不需要重启电脑的软件安装上,当没有这类软件能够安装的时候,使得所有能够进行安装但是需要重启才能生效的所有软件都安装上然后重启。

那么整个过程就是一个拓扑排序的过程。

直接模拟就行了。

Ac代码:

#include<stdio.h>
#include<string.h>
#include<iostream>
#include<vector>
#include<map>
#include<queue>
using namespace std;
vector<int>mp[15000];
char a[15000];
int vis[15000];
int degree[15000];
int n;
void add(int from,int to)
{
degree[to]++;
mp[from].push_back(to);
}
void Slove()
{
int output=0;
queue<int>s;
queue<int>q;
for(int i=1;i<=n;i++)
{
if(degree[i]==0)
{
if(vis[i]==1)
{
q.push(i);
}
else s.push(i);
}
}
while(s.size()>0||q.size()>0)
{
if(s.size()>0)
{
int u=s.front();s.pop();
for(int i=0;i<mp[u].size();i++)
{
int v=mp[u][i];
degree[v]--;
if(degree[v]==0)
{
if(vis[v]==0)s.push(v);
else q.push(v);
}
}
}
else
{
output++;
while(!q.empty())
{
int u=q.front();q.pop();
s.push(u);
}
}
}
printf("%d\n",output);
}
int main()
{
int t;
int kase=0;
scanf("%d",&t);
getchar();
gets(a);
while(t--)
{
n=0;
memset(vis,0,sizeof(vis));
memset(degree,0,sizeof(degree));
map<string,int>s;
while(gets(a))
{
if(strcmp(a,"")==0)break;
else
{
int u;
int cnt=0;
char tmp[2000];
int len=strlen(a);
for(int i=0;i<len;i++)
{
if(a[i]==':'||a[i]=='*')
{
tmp[cnt]='\0';
if(s[tmp]==0)s[tmp]=++n;
u=s[tmp];
if(a[i]=='*')i+=2,vis[u]=1;
if(a[i]==':')i++;
cnt=0;
}
else if(a[i]==' ')
{
tmp[cnt]='\0';
if(s[tmp]==0)s[tmp]=++n;
int v=s[tmp];
add(v,u);
cnt=0;
}
else
{
tmp[cnt++]=a[i];
if(i==len-1)
{
tmp[cnt]='\0';
if(s[tmp]==0)s[tmp]=++n;
int v=s[tmp];
add(v,u);
cnt=0;
}
}
}
}
}
printf("Case %d: ",++kase);
Slove();
for(int i=1;i<=n;i++)mp[i].clear();
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  Hdu 5098