题意:
有三台电脑,n个游戏,给出每个游戏在哪台电脑上完,并且给出哪些游戏必须在另外一些游戏之前玩,玩一个游戏要花1小时,换电脑也要花1小时,而且换电脑必须按1-2-3-1的顺序换,问如何才能花最少的时间玩完所有的游戏。
思路:
先用vector按游戏先后顺序将一张图,然后枚举从第1或第2或第3台电脑开始玩,算出玩完所有游戏的时间,从中取最小。算玩完所有游戏的时间可以根据拓扑排序方法,先把在当前电脑上能玩的所有游戏都玩完后才按顺序换下一台。
#include<cstdio>
#include<vector>
#include<queue>
#include<cstring>
#include<algorithm>
using namespace std;
const int INF=0x3f3f3f3f;
const int MAX=205;
int n,c[MAX],in[MAX],iin[MAX];
vector<int> mp[MAX];
int BFS(int k){
queue<int> Q[5];
for(int i=1;i<=n;i++){
if(in[i]==0){
Q[c[i]].push(i);
}
}
for(int i=1;i<=n;i++){
iin[i]=in[i];
}
int step=-1;
while(!Q[1].empty()||!Q[2].empty()||!Q[3].empty()){
step++;
while(!Q[k].empty()){
int u=Q[k].front();
Q[k].pop();
step++;
int nc=mp[u].size();
for(int i=0;i<nc;i++){
int v=mp[u][i];
iin[v]--;
if(iin[v]==0){
Q[c[v]].push(v);
}
}
}
if(k==1) k=2;
else if(k==2) k=3;
else if(k==3) k=1;
}
if(step!=-1) return step;
else return 0;
}
int main(){
scanf("%d",&n);
for(int i=1;i<=n;i++){
scanf("%d",&c[i]);
}
int nc,v;
memset(in,0,sizeof(in));
for(int i=1;i<=n;i++){
scanf("%d",&nc);
while(nc--){
scanf("%d",&v);
mp[v].push_back(i);
in[i]++;
}
}
int ans=INF;
for(int k=1;k<=3;k++){
int tmp=BFS(k);
ans=min(ans,tmp);
}
printf("%d\n",ans);
return 0;
}