poj 3249(bfs+dp或者记忆化搜索)
题目链接:http://poj.org/problem?id=3249
思路:dp[i]表示到点i的最大收益,初始化为-inf,然后从入度为0点开始bfs就可以了,一开始一直TLE,然后优化了好久才4000ms险过。
之后有写了个dfs记忆化搜索,果然快多了。
bfs AC code:
1 #include<iostream> 2 #include<cstdio> 3 #include<cstring> 4 #include<algorithm> 5 #include<queue> 6 using namespace std; 7 #define MAXN 100100 8 #define MAXM 2002000 9 #define inf 1<<30 10 11 struct Edge{ 12 int v,next; 13 }edge[MAXM]; 14 15 int n,m,NE; 16 int head[MAXN]; 17 18 void Insert(int u,int v) 19 { 20 edge[NE].v=v; 21 edge[NE].next=head[u]; 22 head[u]=NE++; 23 } 24 25 int In_degree[MAXN],Out_degree[MAXN]; 26 int dp[MAXN],value[MAXN]; 27 bool mark[MAXN]; 28 29 void bfs() 30 { 31 queue<int>que; 32 fill(dp,dp+1+n,-inf); 33 memset(mark,false,(n+2)*sizeof(bool)); 34 for(int i=1;i<=n;i++)if(In_degree[i]==0){ 35 mark[i]=true; 36 dp[i]=value[i]; 37 que.push(i); 38 } 39 while(!que.empty()){ 40 int u=que.front(); 41 que.pop(); 42 mark[u]=false; 43 for(int i=head[u];i!=-1;i=edge[i].next){ 44 int v=edge[i].v; 45 if(dp[u]+value[v]>dp[v]){ 46 dp[v]=dp[u]+value[v]; 47 if(!mark[v]){ 48 mark[v]=true;que.push(v); 49 } 50 } 51 } 52 } 53 } 54 55 56 int main() 57 { 58 int u,v,ans; 59 while(~scanf("%d%d",&n,&m)){ 60 NE=0; 61 memset(head,-1,(n+2)*sizeof(int)); 62 memset(In_degree,0,(n+2)*sizeof(int)); 63 memset(Out_degree,0,(n+2)*sizeof(int)); 64 for(int i=1;i<=n;i++)scanf("%d",&value[i]); 65 while(m--){ 66 scanf("%d%d",&u,&v); 67 Insert(v,u); 68 In_degree[u]++; 69 Out_degree[v]++; 70 } 71 bfs(); 72 ans=-inf; 73 for(int i=1;i<=n;i++){ 74 if(Out_degree[i]==0)ans=max(ans,dp[i]); 75 } 76 printf("%d\n",ans); 77 } 78 return 0; 79 }
dfs 记忆化 AC code:
1 #include<iostream> 2 #include<cstdio> 3 #include<cstring> 4 #include<algorithm> 5 #include<queue> 6 using namespace std; 7 #define MAXN 100100 8 #define MAXM 2002000 9 #define inf 1<<30 10 11 struct Edge{ 12 int v,next; 13 }edge[MAXM]; 14 15 int n,m,NE; 16 int head[MAXN]; 17 18 void Insert(int u,int v) 19 { 20 edge[NE].v=v; 21 edge[NE].next=head[u]; 22 head[u]=NE++; 23 } 24 25 int In_degree[MAXN],Out_degree[MAXN]; 26 int dp[MAXN],value[MAXN]; 27 28 int dfs(int u) 29 { 30 if(dp[u]!=-inf)return dp[u]; 31 dp[u]=value[u]; 32 int ans=-inf; 33 for(int i=head[u];i!=-1;i=edge[i].next){ 34 int v=edge[i].v; 35 ans=max(ans,dfs(v)); 36 } 37 if(ans!=-inf){ 38 dp[u]+=ans; 39 } 40 return dp[u]; 41 } 42 43 int main() 44 { 45 int u,v,ans; 46 while(~scanf("%d%d",&n,&m)){ 47 NE=0; 48 memset(head,-1,(n+2)*sizeof(int)); 49 memset(In_degree,0,(n+2)*sizeof(int)); 50 memset(Out_degree,0,(n+2)*sizeof(int)); 51 for(int i=1;i<=n;i++)scanf("%d",&value[i]); 52 while(m--){ 53 scanf("%d%d",&u,&v); 54 Insert(u,v); 55 In_degree[v]++; 56 Out_degree[u]++; 57 } 58 ans=-inf; 59 fill(dp,dp+1+n,-inf); 60 for(int i=1;i<=n;i++){ 61 if(In_degree[i]==0){ 62 ans=max(ans,dfs(i)); 63 } 64 } 65 printf("%d\n",ans); 66 } 67 return 0; 68 }