继续深搜题,不算难,但又碰到恶心的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){
//initialize
for(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);
//initialize
memset(visit,0,100);
cur = -1;
visited = 0;
curColor = -1;
dfs(k2);
}
else{
for(int i=0;i<N;i++){
dfs(i);
//initialize
memset(visit,0,100);
cur = -1;
visited = 0;
curColor = -1;
}
}
cout<<res<<endl;
//initialize
}
return 0;
}