题目描述
Professor Q develops a new software. The software consists of N modules which are numbered from 1 to N. The i-th module will be started up by signal Si. If signal Si is generated multiple times, the i-th module will also be started multiple times. Two different modules may be started up by the same signal. During its lifecircle, the i-th module will generate Ki signals: E1, E2, …, EKi. These signals may start up other modules and so on. Fortunately the software is so carefully designed that there is no loop in the starting chain of modules, which means eventually all the modules will be stoped. Professor Q generates some initial signals and want to know how many times each module is started.
思路
其实这题就是在描述算法导论上的一个思想,两个进程之间通过进程-信号-进程的方式向连接,如果这个图存在环的话,整个进程会永远无法停止,反之则存在可能停止.
所以,我们发现,如果A-B两个进程通过这样的方式向连,那么我们想要求出B进程的启动次数,就需要先求出A进程的启动次数,也就是逆DAG进行DP。转移方程如下:
这样,就可以解决这个问题了.
代码
#include<iostream>
#include<cstring>
#include<cstdio>
#include<algorithm>
#include<vector>
#include<map>
#include<queue>
using namespace std;
#define MAXN 100005
const int MOD = 142857;
map<int,vector<int> >msi;
map<int,vector<int> > ism;
vector<int> start;
int dp[MAXN];
bool vis[MAXN];
int s[MAXN];
int t,n,m;
void Init()
{
msi.clear();
ism.clear();
start.clear();
memset(dp,0,sizeof(dp));
memset(vis,false,sizeof(vis));
return;
}
int Dfs(int cur)
{
if(!vis[cur])vis[cur]=true;
else return dp[cur];
int i;
int w = s[cur];
for(i=0;i<ism[w].size();i++){
int tmp2 = ism[w][i];
dp[cur] = (dp[cur] + Dfs(tmp2))%MOD;
}
return dp[cur];
}
int main()
{
//freopen("input","r",stdin);
int i,j;
int tmp1,tmp2;
scanf("%d",&t);
while(t--){
Init();
scanf("%d%d",&n,&m);
for(i=0;i<m;i++){
scanf("%d",&tmp1);
start.push_back(tmp1);
}
for(i=0;i<n;i++){
scanf("%d %d",&tmp1,&tmp2);
msi[tmp1].push_back(i);
s[i] = tmp1;
for(j=0;j<tmp2;j++){
scanf("%d",&tmp1);
ism[tmp1].push_back(i);
}
}
for(i=0;i<start.size();i++){
tmp1 = start[i];
for(j=0;j<msi[tmp1].size();j++){
tmp2 = msi[tmp1][j];
dp[tmp2]++;
}
}
for(i=0;i<n;i++){
if(!vis[i])Dfs(i);
}
for(i=0;i<n;i++){
printf("%d%c",dp[i],i==n-1?'\n':' ');
}
}
return 0;
}