hihocoder1136-DAG和DP的关系

来源:互联网 发布:java图书管理系统界面 编辑:程序博客网 时间:2024/06/16 03:24

题目描述

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。转移方程如下:

DP[i]=DP[j],forjcantriggeri

这样,就可以解决这个问题了.

代码

#include<iostream>#include<cstring>#include<cstdio>#include<algorithm>#include<vector>#include<map>#include<queue>using namespace std;#define MAXN 100005const 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;}
0 0
原创粉丝点击