poj1691 Painting A Board
1 #include<cstring> 2 #include<iostream> 3 using namespace std; 4 struct node{ 5 int x1,y1,x2,y2,color; 6 }G[15]; 7 int n,ans,deg[15];//n表区域的个数,ans存储最终结果,deg存储拓扑图中各点的入度 8 bool vis[15],m[15][15];//vis用于标记是否访问过,m表示各点之间的联系 9 void buildG()//建立拓扑图,用于确定优先级 10 { 11 for(int i=0;i<n;++i) 12 for(int j=0;j<n;++j) 13 if(G[i].y2==G[j].y1&&!(G[i].x2<G[j].x1||G[j].x2<G[i].x1)){ 14 m[i][j]=1;//建立关系网 15 deg[j]++;//入度+1 16 } 17 } 18 void dfs(int dep,int cnt,int curC)//深度优先搜索 19 { 20 if(cnt>=ans) return;//剪枝,假如当前取画笔次数已大于之前结果,直接返回 21 if(dep==n){//到达解答树目标状态,保存ans值,因前面有cnt>=ans时退出,所以当前cnt较小 22 ans=cnt; 23 return; 24 } 25 int i,j; 26 for(i=0;i<n;++i) 27 if(!deg[i]&&!vis[i]){//找入度为0且还未着色的点开始, 28 vis[i]=1; 29 for(j=0;j<n;++j) 30 if(m[i][j]) 31 deg[j]--;//子节点入度减一 32 if(G[i].color==curC) dfs(dep+1,cnt,curC);//与当前颜色符合,只需往下遍历 33 else dfs(dep+1,cnt+1,G[i].color);//否则,换画笔及颜色 34 for(j=0;j<n;++j) 35 if(m[i][j]) 36 deg[j]++;//递归结束后,还原其初始状态 37 vis[i]=0;//标志取消 38 } 39 } 40 int main() 41 { 42 int i,j,T; 43 cin>>T; 44 while(T--) 45 { 46 cin>>n; 47 for(i=0;i<n;++i) 48 cin>>G[i].y1>>G[i].x1>>G[i].y2>>G[i].x2>>G[i].color; 49 memset(m,0,sizeof(m)); 50 memset(deg,0,sizeof(deg)); 51 buildG(); 52 ans=15; 53 dfs(0,0,0);//都从0开始 54 cout<<ans<<endl; 55 } 56 return 0; 57 }
//DFS+拓扑排序