SRM 665 Med Div2 LuckyCycle
問題文
TopCoder Statistics - Problem Statement
n個のノードとn-1個のedge(無向辺)からなる木がある(閉路がない)。
edgeには重さが4か7どちらかである。
たどっていったedgeの重さが4の個数と7の個数が一致する閉路を作れるようにふたつのノード間で繋がっていないエッジを追加しなさい(作れない場合は追加しない)。
解法
深さ優先探索で4の個数と7の個数を数えていき|4の個数-7の個数|=1になる時のノードを根(スタート地点)とつないで閉路を作ればいい。
注意する事は深さ優先探索で全てのノードがスタート地点になる場合をためす事が必要である。
#include <iostream> #include <vector> #include <stdlib.h> using namespace std; #define WHITE 0 #define GRAY 1 #define BLACK 2 class LuckyCycle{ public: vector<pair<int,int> > PQ[150]; vector<int> answer; int seven_count; int color[150]; int four_count; int need_cost; int start; int goal; void dfs(int u){ pair<int,int>f; color[u]=GRAY; if((seven_count>1 || four_count>1) && abs(seven_count - four_count)==1 && four_count > seven_count){ goal=u; need_cost=7; } if((seven_count>1 || four_count>1) && abs(seven_count - four_count)==1 && seven_count > four_count){ goal=u; need_cost=4; } for(int i=0; i<PQ[u].size(); i++){ f=PQ[u][i]; if(color[f.first]==WHITE){ if(f.second==4)four_count++ ; else if(f.second==7)seven_count++ ; dfs(f.first); if(f.second==4)four_count--; else if(f.second==7)seven_count--; } } color[u]=BLACK; } vector<int>getEdge(vector <int> edge1,vector<int> edge2,vector<int> weight){ for(int i=0; i<edge1.size(); i++){ PQ[edge1[i]].push_back(make_pair(edge2[i],weight[i])); PQ[edge2[i]].push_back(make_pair(edge1[i],weight[i])); } for(int i=0; i<=edge1.size(); i++){ seven_count=0; four_count=0; need_cost=0; goal=-1; start=i+1; for(int j=0; j<=edge1.size(); j++)color[j+1]=WHITE; dfs(start); if(goal!=-1 && need_cost!=0)break; } if(goal!=-1 && need_cost!=0){ answer.push_back(start); answer.push_back(goal); answer.push_back(need_cost); } return answer; } };