参考uva 10160 Servicing Stations(DFS+剪枝)
#include "stdio.h" #include "string.h" #include "algorithm" using namespace std; //map保存联通关系,vis保存是否有服务,son记录每个点与他联通点的个数 int map[40][40],vis[40],son[40],n,m,ans; bool cmp(int x,int y) { return x>y; } //cur当前搜索的位置,cnt当前联通点的数量,sum服务站的数量 void dfs(int cur ,int cnt ,int sum) { int i,k; if(sum>=ans) return;//某条路未搜索完,服务站数量就大于之前最小的答案 if(cnt==n) ans=sum; for(i=1;i<cur;i++)//某点未联通服务,且与之相关的点都已经搜索过 if(!vis[i]&&map[i][0]<cur) return; dfs(cur+1,cnt,sum); k=0;//记录某点成为服务站后新增加的有服务点的个数 int li[40];//记录有新增加有服务点的标号 for(i=0;i<son[cur];i++) { if(vis[map[cur][i]]==0) { vis[map[cur][i]]=1; li[k++]=map[cur][i]; } } if(!k) return;//新增加有服务点的数目为零 dfs(cur+1,cnt+k,sum+1);//搜索下一个 for(i=0;i<k;i++)//回溯,将所有上面新增点恢复未服务状态 vis[li[i]]=0; } int main() { int i,j,a,b; while(~scanf("%d%d",&n,&m)&&n&&m) { memset(vis,0,sizeof(vis)); memset(map,0,sizeof(map)); memset(son,0,sizeof(son)); ans=n+1; for(i=0;i<m;i++) { scanf("%d%d",&a,&b); map[a][son[a]++]=b; map[b][son[b]++]=a; } for(i=1;i<=n;i++) { map[i][son[i]++]=i;//将其中一点与自己相同,防止最后一点为服务站时出错 sort(map[i],map[i]+son[i],cmp); } dfs(1,0,0); printf("%d\n",ans ); } return 0; }