pku 3160 Father Christmas flymouse
2011-09-26 17:55
447 查看
题目来源:http://poj.org/problem?id=3160
强连通+DP
题目大意:圣诞节要到了,flymouse要给他的队友们送去礼物,,n个队友住在n个不同的房子里,每个队友住的地方都有一个comfort index (positive or negative);
他每给一个队友送去礼物,都将得到该队友的comfort index ,问最后他能获得的maximized sum of accumulated comfort indices;
不过题目还有其他的要求:follow directed paths to visit one room after another and give out gifts en passant until he could reach no more unvisited rooms。
思路:根据题目要求,可以先进行缩点,因为一个强连通分量里面的所有点,如果能访问其中一个那这个分量里面的所有点都能访问到, 题目要求最大,所以只访问权值为正的点。
缩点之后的每个点都有一个非负的权值。
下面可以有两种解法:
1. 再重新建图,从入读为0的点开始先下访问,找到最大值。
2. 建立反向图,下面就利用拓扑排序的思想。
很明显2的效率要高一点。
2的代码:
View Code
强连通+DP
题目大意:圣诞节要到了,flymouse要给他的队友们送去礼物,,n个队友住在n个不同的房子里,每个队友住的地方都有一个comfort index (positive or negative);
他每给一个队友送去礼物,都将得到该队友的comfort index ,问最后他能获得的maximized sum of accumulated comfort indices;
不过题目还有其他的要求:follow directed paths to visit one room after another and give out gifts en passant until he could reach no more unvisited rooms。
思路:根据题目要求,可以先进行缩点,因为一个强连通分量里面的所有点,如果能访问其中一个那这个分量里面的所有点都能访问到, 题目要求最大,所以只访问权值为正的点。
缩点之后的每个点都有一个非负的权值。
下面可以有两种解法:
1. 再重新建图,从入读为0的点开始先下访问,找到最大值。
2. 建立反向图,下面就利用拓扑排序的思想。
很明显2的效率要高一点。
2的代码:
View Code
# include<stdio.h> # include<string.h> # include<queue> # define N 30005 # define M 150005 using namespace std; struct node{ int from,next,to; }edge1[M],edge2[M],edge[M]; int head ,tol1,head1 ,head2 ,tol2,val ,visit1 ,visit2 ,V ,tol; int T ,Belong ,DP ,in ,Tcnt,Bcnt,Max,visit ; queue<int>S; void Add(int a,int b) { edge1[tol1].from=a;edge1[tol1].to=b;edge1[tol1].next=head1[a];head1[a]=tol1++; edge2[tol2].from=b;edge2[tol2].to=a;edge2[tol2].next=head2[b];head2[b]=tol2++; } void add(int a,int b) { edge[tol].from=a;edge[tol].to=b;edge[tol].next=head[a];head[a]=tol++; } void dfs1(int i) { int j,v; visit1[i]=1; for(j=head1[i];j!=-1;j=edge1[j].next) { v=edge1[j].to; if(!visit1[v]) dfs1(v); } T[Tcnt++]=i; } void dfs2(int i) { int j,v; visit2[i]=1; Belong[i]=Bcnt; if(val[i]>0) V[Bcnt]+=val[i]; for(j=head2[i];j!=-1;j=edge2[j].next) { v=edge2[j].to; if(!visit2[v]) dfs2(v); } } int main() { int i,n,m,a,b,j,v,cur; while(scanf("%d%d",&n,&m)!=EOF) { for(i=0;i<n;i++) scanf("%d",&val[i]); tol1=tol2=0; memset(head1,-1,sizeof(head1)); memset(head2,-1,sizeof(head2)); for(i=0;i<m;i++) { scanf("%d%d",&a,&b); Add(a,b); } memset(visit1,0,sizeof(visit1)); memset(visit2,0,sizeof(visit2)); memset(V,0,sizeof(V)); Tcnt=Bcnt=0; for(i=0;i<n;i++) if(!visit1[i]) dfs1(i); for(i=Tcnt-1;i>=0;i--) { if(!visit2[T[i]]) { dfs2(T[i]); Bcnt++; } } tol=0; memset(head,-1,sizeof(head)); memset(in,0,sizeof(in)); for(i=0;i<m;i++) { a=edge1[i].from; b=edge1[i].to; if(Belong[a]==Belong[b]) continue; add(Belong[b],Belong[a]);//建立反向边 in[Belong[a]]++; } memset(DP,0,sizeof(DP)); Max=0; memset(visit,0,sizeof(visit)); for(i=0;i<Bcnt;i++) { if(in[i]==0) S.push(i); } while(!S.empty()) { cur=S.front(); S.pop(); for(j=head[cur];j!=-1;j=edge[j].next) { v=edge[j].to; if(visit[v]<V[cur]) visit[v]=V[cur]; in[v]--; if(in[v]==0) { V[v]+=visit[v]; S.push(v); } } if(V[cur]>Max) Max=V[cur]; } printf("%d\n",Max); } return 0; }
相关文章推荐
- poj 3160 Father Christmas flymouse (SCC缩点+SPFA求最长路)
- POJ - 3160 Father Christmas flymouse(最长路+强连通分量)
- poj 3160 Father Christmas flymouse (spfa + 强联通)
- poj 3160 Father Christmas flymouse(强连通+dp)
- POJ 3160 Father Christmas flymouse(强连通分量+spfa最长路)
- poj 3160 Father Christmas flymouse(强连通缩点+最长路)
- POJ 3160 Father Christmas flymouse
- POJ 3160 Father Christmas flymouse
- POJ 3160 Father Christmas flymouse
- POJ 3160 Father Christmas flymouse(强连通+DP)
- poj 3160 Father Christmas flymouse(Tarjan+SPFA)
- poj 3160 Father Christmas flymouse
- poj 3160 Father Christmas flymouse (强连通分量+记忆化搜素)
- POJ 3160 Father Christmas flymouse Tarjon+DP
- poj 3160-Father Christmas flymouse-强连通
- POJ 3160 Father Christmas flymouse
- POJ3160-Father Christmas flymouse (强连通缩点+dfs)
- POJ-3160-Father Christmas flymouse 解题报告
- POJ 3160 Father Christmas flymouse 强连通+最长路
- PKU 3013 Big Christmas Tree 最短路 spfa