HDU5098 Smart Software Installer (top排序)

来源:互联网 发布:网络受到攻击 编辑:程序博客网 时间:2024/04/30 00:51

题目意思:有一批软件需要安装,“:”前的软件需要在“:”后的软件安装完成后才能安装(“:”后面可能有多个软件),“*”表明该软件需要重启才完成安装。

求所有软件都完成安装最少重启的次数。

解题思路:

双队列top排序,用两个队列q1,q2分别来存不需要重启的软件和需要重启的软件。首先将入度的0的点加进队列,当然不需要重启的进q1,需要重启的进q2。然后删除q1中的所有节点,让与他们相连的节点的入度减1,如果发现减完入度为0,再判断其是否需要重启,并加进q1 or q2。一旦发现q1为空,那么使答案加1(即重启一次),把q2中所有元素加入q1,q2清空。如此循环直到q1,q2均为空即可。

#include<iostream>#include<cstdio>#include<cstring>#include<algorithm>#include<string>#include<vector>#include<queue>#include<set>#include<map>#include<cmath>#define INF 0xfffffff#define MAX 1000000#define CLR(a,b) memset((a),(b),sizeof(a) )using namespace std;typedef long long ll;int edge[2005][2005];int vis[2005];int degree[2005];int tot,ans;map<string,int>mp;queue<int>q1,q2;void top_sort(){    for(int i=1;i<=tot;i++)    if(!degree[i]){        if(!vis[i]) q1.push(i);        else q2.push(i);    }    while(!q1.empty()||!q2.empty()){        if(q1.empty()&&!q2.empty()){            ans++;            while(!q2.empty()){                int x=q2.front();                q2.pop();                q1.push(x);            }        }        while(!q1.empty()){            int x=q1.front();            q1.pop();            for(int i=1;i<=tot;i++)            if(edge[i][x]){                degree[i]--;                if(!degree[i]){                    if(!vis[i]) q1.push(i);                    else q2.push(i);                }            }        }    }}void init(){    CLR(degree,0);    CLR(edge,0);    CLR(vis,0);    tot=0;    ans=0;    mp.clear();    while(!q1.empty()) q1.pop();    while(!q2.empty()) q2.pop();}string p,last[1005];int main(){    int a,b;    int t;    string s;    scanf("%d",&t);    getchar();    getchar();    for(int cas=1;cas<=t;cas++){        init();        while(getline(cin,s)!=NULL){            if(s[0]=='\0') break;            int len=s.size();            int flag=0;            int havelast=0;            p="";            int lastnum=-1;            for(int i=0;i<len;i++){                if(s[i]==' '){                    last[++lastnum]="";                    continue;                }                if(s[i]=='*'){                    flag=1;                    continue;                }                if(s[i]==':'){                    havelast=1;                    continue;                }                if(havelast==0) p+=s[i];                else last[lastnum]+=s[i];            }            if(mp.find(p)==mp.end()) mp[p]=++tot;            vis[mp[p]]=flag;            int m=0;            while(last[m].size() > 0 && m <= lastnum){                if(mp.find(last[m])==mp.end()) mp[last[m]]=++tot;                edge[mp[p]][mp[last[m]]]=1;                m++;            }        }        for(int i=1;i<=tot;i++)            for(int j=1;j<=tot;j++)            if(edge[i][j]) degree[i]++;        top_sort();        cout<<"Case "<<cas<<": "<<ans<<endl;    }    return 0;}


0 0
原创粉丝点击