A pay cable TV network plans to relay an important football match. Their broadcast network and user terminal constitute a tree structure, the root node of the tree is located at the scene of the football match, the leaves for each user terminal, and other transit points for the tree's internal nodes.
Signal transmission costs from the retransmission station to the retransmission station and from the retransmission station to all user terminals are known, and the total cost of a retransmission is equal to the sum of the cost of the transmitted signal.
Now each user is prepared for a fee to watch this wonderful football game, the cable network has the right to decide which users will be given a signal without giving them a signal.
Write a program to find a solution that allows the cable network to make as many users as possible to watch the broadcast without losing money.
Input format:
The first line of the input file contains two integers separated by spaces N and M, where 2≤n≤3000,1≤m≤n-1,n is the total number of nodes for the entire CATV network, and M is the number of user terminals.
The first retransmission station is the tree root node number is 1, the other broadcast station number 2 to N-M, the user terminal number is n-m+1 to n.
Each line of the next N-m line represents the data of a broadcast station, and section i+1 indicates the data of the retransmission station, which is in the following format:
K A1 C1 A2 C2 ... Ak Ck
K indicates that the retransmission station is next to K nodes (retransmission station or user), each node corresponds to a pair of integers a and c,a represents the node number, C represents the cost of transmitting the signal from the current retransmission station to Node A. The last line in turn represents the amount of money that all users are prepared to pay for watching the game.
Output format:
The output file has only one row and contains an integer that represents the maximum number of users required for the above problem.
The problem on the Internet is mostly unclear, and did not give a real complexity, only said that there are many States can not be achieved, perfunctory.
First of all, I believe you can have a second look at the N3 of the tree DP, the first point has a J customer minimum cost (can be negative).
N2 status, O (n) transfer.
What about the positive solution?
The positive solution is to testify the complexity of the method above.
You can try to construct a card out of this method of data, and then you will find that the maximum complexity of a single time is N2/4, but the cost of a single high complexity is the overall complexity is also N2/4.
Yes, this problem each node if its sub-nodes, so that the current operation of a high degree of complexity, it can not contribute to other points, and all its child nodes will be merged, can not again produce N2 level of contribution (if produced, this operation complexity is far less than N2, relatively negligible), at the same time, For a fixed parent node, fixed its size, we can find, set size to K, have Q subtree, sub-tree size s[i], contribute to s[1]*s[2]+ (S[1]+s[2]) *s[3]+ (s[1]+s[2]+s[3]) *s[4]+ ..... and S[i] and less than or equal to the size parent node.
If the subtree is the same, there are Q subtrees, and the parent node has a size of K
Contribution to (Q-1) * ((k/q) 2) (q>=2), obviously q=2, and the optimal substructure will bring K2/4 contribution.
Feel it.
#include <bits/stdc++.h>#defineINF 0x3f3f3f3fusing namespacestd;intcnt,dp[3005][3005],n,m,head[3006],u[3005];structedge{intNext,to,val;} e[8000];inlinevoidInsertintFrintTo,intVal) {e[++cnt].to=to;e[cnt].next=head[fr];head[fr]=cnt;e[cnt].val=Val;}intDfsintp) {dp[p][0]=0;ints,g=0; for(intI=head[p];i;i=E[i].next) { if(e[i].to>n-m) {e[i].val-=U[e[i].to]; G++; for(intj=g;j>=0; j--) {Dp[p][j]=min (dp[p][j],dp[p][j-1]+e[i].val); } Continue; } s=dfs (e[i].to); g+=s; for(intj=g;j>=0; j--) for(intk=0; k<=s;k++) {Dp[p][j]=min (dp[p][j],dp[e[i].to][k]+dp[p][j-k]+e[i].val); } } returnG;}intMain () {memset (DP,0x3f,sizeof(DP)); scanf ("%d%d", &n,&m);intq,a,b; for(intI=1; i<=n-m;i++) {scanf ("%d",&q); for(intj=1; j<=q;j++) {scanf ("%d%d",&a,&b); Insert (I,A,B); } } for(intI=1; i<=m;i++) scanf ("%d", &u[n-m+i]); DFS (1);intMa=0; for(inti=n;i>=0; i--) { if(dp[1][i]<=0) {Ma=i; Break; }} printf ("%d\n", MA); return 0;}
View Code
Luogu 1273 Cable TV network