pku 3249

传说中的神题吧。。。。。wa了n次才过。。。简单拓扑+dp。。。。

掌握节点之间的递推关系。。与层次关系! 那么关系到层次关系 显然就离不开拓扑了,再进行dp求解。。。。

但是这里有一个很大的问题就是很有可能是负解,所以一开始要注意处理初始数据 ,依题意应该是-2000000001;

代码:

#include<iostream> #include<stdio.h> #include<string.h> using namespace std; const int MAX1=100004; const int MAX2=1000008; const int inf=2000000001; struct Gragh { int id; int next; }; Gragh GA[MAX1+MAX2]; int cnt[MAX1]; int out[MAX1]; int value[MAX1]; int record[MAX1]; int Tsot[MAX1]; int n,m,G_end,k,Max; void init() { k=1,Max=-inf; memset(cnt,0,sizeof(cnt)); memset(out,0,sizeof(out)); memset(GA,0,sizeof(GA)); } void Bulid(int s,int e) { int p=s; while(GA[p].next) p=GA[p].next; GA[G_end].id=e; GA[p].next=G_end; G_end++; } bool Topsort() { int top=-1; for(int i=1;i<=n;i++) if(cnt[i]==0) { record[i]=value[i]; cnt[i]=top; top=i; } for(int i=1;i<=n;i++) { if(top==-1) return false; int j=top; top=cnt[top]; Tsot[k++]=j; int p,q; p=GA[j].next; while(p) { q=GA[p].id; if(--cnt[q]==0) { cnt[q]=top; top=q; } p=GA[p].next; } } } void dp() { for(int i=1;i<=n;i++) { int temp=Tsot[i]; int p,q; p=GA[temp].next; while(p) { q=GA[p].id; if(record[temp]+value[q]>record[q]) record[q]=record[temp]+value[q]; p=GA[p].next; } } } int main() { while(scanf("%d%d",&n,&m)!=EOF) { G_end=n+1; init(); for(int i=1;i<=n;i++) { scanf("%d",&value[i]); record[i]=-inf; } int s,e; for(int i=0;i<m;i++) { scanf("%d%d",&s,&e); Bulid(s,e); cnt[e]++; out[s]++; } Topsort(); dp(); for(int i=1;i<=n;i++) if(out[i]==0) Max=max(Max,record[i]); printf("%d/n",Max); } return 0; }

你可能感兴趣的:(pku 3249)