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

 

 

你可能感兴趣的:(poj)