[zoj4045][思维+dfs]
Posted mekakucityactor
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了[zoj4045][思维+dfs]相关的知识,希望对你有一定的参考价值。
http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode=4045
题意:给一棵树。这棵树有n个节点,问你这个图能不能分成k个分块。这个分块内所有的节点都至少与一个该块中的其他节点有一条边相连。
题目分析:由于是无根树,所以可以随便选取一个结点作为根节点,然后dfs往下搜索,搜索过程不容易划分哪些结点和哪些结点是一块,而利用搜索到叶子结点之后往上回溯的过程,每累积n/k个点就划分一次,就很容易划分出结点块.这道题也主要是利用了dfs的回溯过程.(很多不容易正向解决的问题回溯起来很容易得到解决)
1 #include <iostream> 2 #include <iomanip> 3 #include <algorithm> 4 #include <map> 5 #include <vector> 6 #include <string> 7 #include <set> 8 #include<cstdio> 9 #include <cmath> 10 #include<cstring> 11 using namespace std; 12 typedef long long ll; 13 bool vis[100005]; 14 int dp[100005]; 15 vector<int>G[100005]; 16 int dfs(int u,int k){ 17 vis[u]=1; 18 int t=1; 19 for(int i=0;i<G[u].size();i++){ 20 if(!vis[G[u][i]]){ 21 t+=dfs(G[u][i],k); 22 } 23 } 24 dp[u]=t; 25 if(dp[u]==k){ 26 dp[u]=0; 27 } 28 return dp[u]; 29 } 30 void dfs_ans(int u,int fa){ 31 if(dp[u]==0&&u!=fa)return; 32 vis[u]=1; 33 if(u!=fa){ 34 printf(" %d",u); 35 } 36 for(int i=0;i<G[u].size();i++){ 37 if(!vis[G[u][i]]){ 38 dfs_ans(G[u][i],u); 39 } 40 } 41 } 42 int main(){ 43 //freopen("in.txt","r",stdin); 44 ios_base::sync_with_stdio(0); 45 cin.tie(NULL); 46 int t; 47 cin>>t; 48 while(t--){ 49 int n,k; 50 cin>>n>>k; 51 // cout <<n<<k<<endl; 52 for(int i=1;i<=n;i++)G[i].clear(); 53 memset(vis,0,sizeof(vis)); 54 memset(dp,0,sizeof(dp)); 55 for(int i=0;i<n-1;i++){ 56 int a,b; 57 cin>>a>>b; 58 G[a].push_back(b); 59 G[b].push_back(a); 60 } 61 dfs(1,k); 62 memset(vis,0,sizeof(vis)); 63 //for(int i=0i<n;i++){if(dp[i]==0){dp[i]=1;printf("%d",i);dfs(i,k,i);dp[i]=0;} 64 if(dp[1]==0){ 65 printf("YES "); 66 for(int i=1;i<=n;i++){ 67 if(dp[i]==0){ 68 printf("%d",i); 69 dfs_ans(i,i); 70 printf(" "); 71 } 72 73 } 74 } 75 else{ 76 printf("NO "); 77 } 78 } 79 return 0; 80 }
以上是关于[zoj4045][思维+dfs]的主要内容,如果未能解决你的问题,请参考以下文章
ZOJ - 3985 - String of CCPC (思维 + 暴力)
ZOJ 1709 Oil Deposits(dfs,连通块个数)
ZOJ 1457 Prime Ring Problem(dfs+剪枝)