洛谷1113 拓扑序

来源:互联网 发布:淘宝达人怎么玩 编辑:程序博客网 时间:2024/06/07 03:43

  这是一道拓扑序的题,首先我们建图,如果i的准备工作是j,就连一条j-->i的边,那么一个工作i可以进行当且仅当i的入度为0,那么我们就需要拓扑排序,f[i]表示完成第i件工作需要的最短时间,则有f[v]=max(f[u])+cost[v],因此我们需要再反向连边,状态转移的顺序就是正向图的拓扑序

#include<cstdio>#include<cstring>#include<algorithm>using namespace std;#define maxn 500000int pre[maxn][2],last[maxn][2],other[maxn][2];int l,ans,n,cost[maxn],in0[maxn],que[maxn],f[maxn];void connect(int x,int y,int z){l++;pre[l][z]=last[x][z];last[x][z]=l;other[l][z]=y;if (z==0) in0[y]++;}int main(){scanf("%d",&n);for (int i=1;i<=n;i++) {int a,c;scanf("%d%d%d",&a,&cost[i],&c);while (c) {connect(c,a,0);connect(a,c,1);scanf("%d",&c);}}int h=1,t=0;for (int i=1;i<=n;i++) if (in0[i]==0) {que[++t]=i;f[i]=cost[i];}while (h<=t) {int u=que[h];h++;for (int p=last[u][0];p;p=pre[p][0]) {int v=other[p][0];in0[v]--;if (in0[v]==0) {que[++t]=v;for (int q=last[v][1];q;q=pre[q][1]) {int v1=other[q][1];f[v]=max(f[v],f[v1]);}f[v]+=cost[v];}}}//for (int i=1;i<=t;i++) printf("%d ",que[i]);for (int i=1;i<=n;i++) ans=max(ans,f[i]);printf("%d\n",ans);return 0;}


0 0
原创粉丝点击