题目链接:https://vjudge.net/problem/HDU-1054
Strategic Game
Time Limit: 20000/10000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)
Total Submission(s): 8673 Accepted Submission(s): 4174
Your program should find the minimum number of soldiers that Bob has to put for a given tree.
The input file contains several data sets in text format. Each data set represents a tree with the following description:
the number of nodes
the description of each node in the following format
node_identifier:(number_of_roads) node_identifier1 node_identifier2 ... node_identifier
or
node_identifier:(0)
The node identifiers are integer numbers between 0 and n-1, for n nodes (0 < n <= 1500). Every edge appears only once in the input data.
For example for the tree:
the solution is one soldier ( at the node 1).
The output should be printed on the standard output. For each given input data set, print one integer number in a single line that gives the result (the minimum number of soldiers). An example is given in the following table:
最小点覆盖:
1 #include<cstdio> 2 #include<cstring> 3 #include<vector> 4 using namespace std; 5 6 vector<int>G[1510]; 7 bool vis[1510]; 8 int match[1510]; 9 10 bool dfs(int u) 11 { 12 for(int i = 0; i<G[u].size(); i++) 13 { 14 int t = G[u][i]; 15 if(!vis[t]) 16 { 17 vis[t] = true; 18 if(match[t]==-1 || dfs(match[t])) 19 { 20 match[t] = u; 21 return true; 22 } 23 } 24 } 25 return false; 26 } 27 28 int main() 29 { 30 int n,m,k,a,ans; 31 while(scanf("%d",&n)==1) 32 { 33 for(int i = 0; i<n; i++) 34 G[i].clear(); 35 for(int i = 0; i<n; i++) 36 { 37 scanf("%d:(%d)",&m,&k); 38 for(int j = 0; j<k; j++) 39 { 40 scanf("%d",&a); 41 G[m].push_back(a); 42 G[a].push_back(m); 43 } 44 } 45 46 ans = 0; 47 memset(match,-1,sizeof(match)); 48 for(int i = 0; i<n; i++) 49 { 50 memset(vis,false,sizeof(vis)); 51 if(dfs(i)) 52 ans++; 53 } 54 55 printf("%d\n",ans/2); 56 } 57 }
树形DP:
1 #include<cstdio> 2 #include<cstring> 3 #include<algorithm> 4 using namespace std; 5 6 struct 7 { 8 int to, next; 9 }e[1510]; 10 11 int h[1510], dp[1510][2], num; 12 13 void addedge(int u, int v) 14 { 15 e[num].to = v; 16 e[num].next = h[u]; 17 h[u] = num++; 18 } 19 20 int dfs(int u) 21 { 22 int v; 23 dp[u][0] = 0; dp[u][1] = 1; 24 for(int i = h[u]; i!=-1; i = e[i].next) 25 { 26 v = e[i].to; 27 dfs(v); 28 dp[u][0] += dp[v][1]; 29 dp[u][1] += min(dp[v][0],dp[v][1]); 30 } 31 return min(dp[u][0], dp[u][1]); 32 } 33 34 int main() 35 { 36 int n,m,u,v,k,rt; 37 while(~scanf("%d",&n)) 38 { 39 memset(h,-1,sizeof(h)); 40 rt = -1; num = 0; 41 for(int i = 0; i<n; i++) 42 { 43 scanf("%d:(%d)",&u,&k); 44 for(int j = 0; j<k; j++) 45 { 46 scanf("%d",&v); 47 addedge(u,v); 48 } 49 50 if(rt==-1) rt = u; 51 } 52 53 printf("%d\n",dfs(rt)); 54 } 55 }