【ZOJ 2103】 Marco Popo the Traveler

来源:互联网 发布:b站视频下载 知乎 编辑:程序博客网 时间:2024/06/10 06:01

题目来源

继续深搜题,不算难,但又碰到恶心的WA,debug若干个小时后才发现没有把非连通图的情况考虑进去,在调用dfs前要调用check函数(也是深搜)检查是否为连通图,如不是则直接打印 "No"。思维严密性还是有点欠缺


#include<iostream>#include<fstream>#include<cstring>#include<vector>#include<map>//#include<map>//#include "debug.h"using namespace std;int N,C,H;bool visit[10][10];int color[10][10];//int h[10];int res = 50;int curColor = -1; //车轮当前颜色int cur = -1;  //当前已更换颜色次数int visited = 0;  //当前已走过的highway总数map<int,vector<int> > tab;int chk[10];  //用于检查是否为联通图void check(int k,int &cnt){if(chk[k] == 2) return;  //已检查过该节点chk[k] = 1;  //正在检查中vector<int> &v = tab[k];for(int i=0;i<v.size();i++){if(chk[v[i]] == 0) check(v[i],cnt);}chk[k] = 2;  //检查完毕cnt++;}void dfs(int k){if(visited == H){ res = min(res,cur); return; } //一种可行方案vector<int> &v = tab[k];for(int i=0;i<v.size();i++){int lastColor = -2;if(!visit[k][v[i]]){visit[v[i]][k] = visit[k][v[i]] = true;if(color[k][v[i]]!=curColor){ cur++;if(cur>=res){  //剪枝,visit[v[i]][k] = visit[k][v[i]] = false;cur--;break;  //跳出循环}else{ lastColor = curColor; curColor = color[k][v[i]]; }}visited++;  //决定访问(k,i)dfs(v[i]);if(lastColor!=-2){curColor = lastColor;  //lastColor!=-2说明此次改变过颜色,回溯到之前的颜色cur--;}visited--;visit[k][v[i]] = visit[v[i]][k] = false;  }}}int main(){//ifstream cin("input.txt");while(cin>>N>>C>>H && (N+C+H)!=0){//initializefor(int i=0;i<N;i++)for(int j=0;j<N;j++) color[i][j] = -3;curColor = -1;res = 50;cur = -1;visited = 0;tab.clear();memset(visit,0,100);memset(chk,0,10*sizeof(int));int a,b,c;for(int i=0;i<H;i++){cin>>a>>b>>c;color[a][b] = color[b][a] = c;if(tab.find(a) == tab.end()) tab[a] = vector<int>(); tab[a].push_back(b);if(tab.find(b) == tab.end()) tab[b] = vector<int>();tab[b].push_back(a);}int odd = 0;for(int i=0;i<N;i++) if(tab[i].size()%2) ++odd;if(odd>2){ cout<<"No\n"; continue;}//检查是否为连通图int cnt = 0;check(0,cnt);if(cnt<N){ cout<<"No\n"; continue;}if(odd == 2){int k1=0,k2=0;while(tab[k1].size()%2==0) k1++;k2 = k1+1;while(tab[k2].size()%2==0) k2++;curColor = -1; dfs(k1);//initializememset(visit,0,100);cur = -1;    visited = 0;curColor = -1;dfs(k2);} else{for(int i=0;i<N;i++){ dfs(i);//initializememset(visit,0,100);cur = -1;visited = 0;curColor = -1;}}cout<<res<<endl;//initialize}return 0;}


0 0
原创粉丝点击