SRM 539 DIV1 Medium SafeReturn

http://apps.topcoder.com/stat?c=problem_statement&pm=11805&rd=14731
追記: (コメント/Editorialより) 想定解(とこの解答)は間違っているらしい
Editorial読んでたのに、そのことに気づかない程度の英語力!

問題

N(1<=N<=49)人の兵士がいて、T(N+1<=T<=50)つの砦がある。
i番目の兵士は砦0から砦iへ向かいたい。
砦同士の道は距離(INFか1〜9)があり、全ての兵士は最小距離で目指す砦へつ行き、そのあとはそこにとどまる。
しかし、道は危険であり、兵士が一人だけで道を通る(危険に晒される)ことはあまりしたくなく、危険に晒される兵士の数をできるだけ少なくしたい。
危険に晒される兵士の数の最小値を求めろ

回答

まず、兵士が二人以上でいるということは、片方の兵士の砦へつくまでもう一人がずっと付き添っており、そのあと自分の砦へ向かう。ということのみである。(ここがあまりわかってない)
http://d.hatena.ne.jp/anta1/20120816/1345046832に書いたが、それをグラフにするとDAGとなり、問題はその最小パス被覆を求める問題となり、二部マッチングする。

コメント

現在もあまりよくわかってない。

コード
#include <string>
#include <vector>
#include <algorithm>
#include <set>
#include <map>
#include <queue>
#include <iostream>
#include <sstream>
#include <cstdio>
#include <cmath>
#include <ctime>
#include <cstring>
#define rep(i,n) for(int (i)=0;(i)<(int)(n);++(i))
#define rer(i,l,u) for(int (i)=(int)(l);(i)<=(int)(u);++(i))
#define reu(i,l,u) for(int (i)=(int)(l);(i)<(int)(u);++(i))
#define each(it,o) for(__typeof(o.begin()) it = o.begin(); it != (o).end(); ++ it)
#define all(o) (o).begin(), (o).end()
#define pb(x) push_back(x)
#define mp(x,y) make_pair((x),(y))
#define mset(m,v) memset(m,v,sizeof(m))
#define INF 0x3f3f3f3f
using namespace std;
typedef long long ll; typedef vector<int> vi; typedef pair<int,int> pii; typedef vector<pii> vpii;

vector<bool> done;
vector<int> match;
vector<vector<int> >e;
bool augment(int i) {
	if(done[i]) return false;
	else done[i] = true;
	each(j, e[i]) if(match[*j] == -1 || augment(match[*j])) {
		match[*j] = i;
		return true;
	}
	return false;
}

struct SafeReturn {
	int minRisk(int N, vector <string> streets) {
		int n = streets.size();
		static int wf[51][51];
		rep(i, n) rep(j, n) wf[i][j] = streets[i][j] == '-' ? (int)INF : streets[i][j] - '0';
		rep(i, n) wf[i][i] = 0;
		rep(k, n) rep(i, n) rep(j, n) {
			if(wf[i][k] != INF && wf[k][j] != INF)
				wf[i][j] = min(wf[i][j], wf[i][k] + wf[k][j]);
		}
		e = vector<vector<int> >(N);
		rep(i, N) rep(j, N) if(i != j && wf[0][i+1] + wf[i+1][j+1] == wf[0][j+1]) e[i].pb(j);
		match = vector<int>(N, -1);
		int count = 0;
		rep(i, N) {
			done = vector<bool>(N, false);
			if(augment(i)) ++ count;
		}
		return N - count;
	}
};