Hdu4971: http://acm.hdu.edu.cn/showproblem.php? PID = 1, 4971
Question: There are n projects for you. Each project has a certain benefit. However, to complete a project, you must first learn some skills and spend some time learning each skill. In addition, before learning a skill, you may need to first learn the previous skill and finally ask you about the maximum benefits you can get.
Question: it is easy to think of network streams. The key is to build a graph. First, split each skill point. The capacity between two points is the cost of each skill. People then build one side and one side on the right side, and the capacity is infinite. Then, each item connects one side to the point on the left of the skill, and the capacity is infinite, then, an edge is established between the source point and each project. capacity is the benefit. The last step is between skills. If you want to learn J skills before learning I skills, then the left endpoint of I is connected to the left endpoint of J, with an infinite capacity. Then run the network stream. The final answer is the total profit minus the total traffic.
1 #include<iostream> 2 #include<cstring> 3 #include<algorithm> 4 #include<cstdio> 5 #include<queue> 6 #define INF 100000000 7 using namespace std; 8 const int N=205; 9 const int M=1000000; 10 struct Node{ 11 int v; 12 int f; 13 int next; 14 }edge[M]; 15 int n,m,u,v,cnt,sx,ex; 16 int head[N],pre[N],visit[N]; 17 int val1[N],val2[N]; 18 void init(){ 19 cnt=0; 20 //memset(edge,0,sizeof(edge)); 21 memset(head,-1,sizeof(head)); 22 } 23 void add(int u,int v,int w){ 24 edge[cnt].v=v; 25 edge[cnt].f=w; 26 edge[cnt].next=head[u]; 27 head[u]=cnt++; 28 edge[cnt].f=0; 29 edge[cnt].v=u; 30 edge[cnt].next=head[v]; 31 head[v]=cnt++; 32 } 33 bool BFS(){ 34 memset(pre,0,sizeof(pre)); 35 pre[sx]=1; 36 queue<int>Q; 37 Q.push(sx); 38 while(!Q.empty()){ 39 int d=Q.front(); 40 Q.pop(); 41 for(int i=head[d];i!=-1;i=edge[i].next ){ 42 if(edge[i].f&&!pre[edge[i].v]){ 43 pre[edge[i].v]=pre[d]+1; 44 Q.push(edge[i].v); 45 } 46 } 47 } 48 return pre[ex]>0; 49 } 50 int dinic(int flow,int ps){ 51 int f=flow; 52 if(ps==ex)return f; 53 for(int i=head[ps];i!=-1;i=edge[i].next){ 54 if(edge[i].f&&pre[edge[i].v]==pre[ps]+1){ 55 int a=edge[i].f; 56 int t=dinic(min(a,flow),edge[i].v); 57 edge[i].f-=t; 58 edge[i^1].f+=t; 59 flow-=t; 60 if(flow<=0)break; 61 } 62 63 } 64 if(f-flow<=0)pre[ps]=-1; 65 return f-flow; 66 } 67 int solve(){ 68 int sum=0; 69 while(BFS()) 70 sum+=dinic(INF,sx); 71 return sum; 72 } 73 int main() { 74 int T,k,temp,sum,tt=1; 75 scanf("%d",&T); 76 while(T--) { 77 scanf("%d%d",&n,&m); 78 sum=0; 79 init(); 80 for(int i=1; i<=n; i++) { 81 scanf("%d",&val1[i]); 82 sum+=val1[i]; 83 } 84 for(int j=1;j<=m;j++) 85 scanf("%d",&val2[j]); 86 for(int i=1;i<=n;i++){ 87 scanf("%d",&k); 88 for(int j=1;j<=k;j++){ 89 scanf("%d",&temp); 90 add(2*m+i,temp+1,INF); 91 } 92 add(0,2*m+i,val1[i]); 93 } 94 for(int i=1;i<=m;i++){ 95 for(int j=1;j<=m;j++){ 96 scanf("%d",&temp); 97 if(temp==1){ 98 add(i,j,INF); 99 }100 }101 }102 for(int i=1;i<=m;i++){103 add(i,i+m,val2[i]);104 add(i+m,2*m+n+1,INF);105 }106 sx=0;ex=2*m+n+1;107 printf("Case #%d: %d\n",tt++,sum-solve());108 }109 return 0;110 }
View code
A simple brute force problem.