cafelier のSRM参加記録です。コンテスト中に考えてたことを執拗に全部書き残すとどうなるだろうかという試み本番中にこういうコードが書きたかったなあ、という後で書いた反省コードを書き残す試み
スパムが来たのでしばらくコメント欄をはてなユーザ限定にしています、すみません、
SRM | |
SRM424 の成績・ソース (要ログイン) : AC/AC/WA : 初参加
// SRM424 Div2 Lv3 : Kruskal's Algorithm #include <vector> #include <string> #include <set> using namespace std; struct BestRoads { vector<int> numberOfRoads(vector<string> roads, int M) { int N = roads.size(); vector<int> ans(N); // 辺を優先度高い順に並べる typedef pair<int,int> road; set<road> Q; for(int i=0; i<N; ++i) for(int j=i+1; j<N; ++j) if( roads[i][j]=='Y' ) Q.insert( road(i,j) ); vector<int> p(N,-1), s(N, 1); int div = N; // Union-Find 用データ。p:親, s:各連結成分のサイズ, div:連結成分の個数 int red = M-N+1; // 拾っておきたい捨て辺の本数 for(set<road>::iterator it=Q.begin(); it!=Q.end(); ++it) { road r = *it; int a=r.first; while(p[a]!=-1) a=p[a]; int b=r.second; while(p[b]!=-1) b=p[b]; if( a != b ) // まだつながってないとこだったらつなげる { ans[r.first]++, ans[r.second]++, div--; if(s[a]<s[b]) p[a]=b, s[b]+=s[a]; else p[b]=a, s[a]+=s[b]; } else if( red ) // 繋がってるところでも優先度高ければ使う ans[r.first]++, ans[r.second]++, red--; } return (red==0 && div==1) ? ans : vector<int>(); } };
presented by cafelier/k.inaba under