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 }
View Code

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 }
View Code

 

 

posted @ 2013-08-26 11:20  ihge2k  阅读(404)  评论(0编辑  收藏  举报