Lilliput Steps

小さな一歩から着実に. 数学やプログラミングのことを書きます.

AOJ 0235 - Sergeant Rian

問題文 : サージェント・ライアン

解法 :
最後に訪れる島を根とした木を作ると, 爆破する橋が必然的に決まる.
ゆえに, 全ての島について最後の島としたときの爆破する時間を考え, その最小値を答えとする.

コード :

#include <cstdio>
#include <cstring>
#include <vector>

#define INF (1 << 30)

using namespace std;

typedef struct {
	int par;
	vector<int> son;
} Node;

Node T[20];
int n;
int cost[20][20];
bool vis[20];
int cSum;

void makeTree(int v, int p)
{
	T[v].par = p;
	vis[v] = true;
	for (int i = 0; i < n; i++){
		if (vis[i] == false && cost[v][i] != INF){
			T[v].son.push_back(i);
			makeTree(i, v);
		}
	}
}

void dfs(int v, int c)
{
	vis[v] = true;
	if (T[v].son.size() == 0){
		return;
	}
	
	for (int i = 0; i < T[v].son.size(); i++){
		if (vis[T[v].son[i]] == false){
			dfs(T[v].son[i], cost[v][T[v].son[i]]);
		}
	}
	cSum += c * 2;
}

int bomb()
{
	cSum = 0;
	int pNode = 0;
	
	while (~pNode){
		dfs(pNode, 0);
		if (~T[pNode].par) cSum += cost[pNode][T[pNode].par];
		pNode = T[pNode].par;
	}
	
	return (cSum);
}

int main()
{
    int a, b, t;
    int res;
    
    while (scanf("%d", &n) && n){
		
		for (int i = 0; i < n; i++){
			for (int j = 0; j < n; j++){
				cost[i][j] = INF;
			}
		}
        
        for (int i = 0; i < n - 1; i++){
            scanf("%d %d %d", &a, &b, &t);
            cost[a - 1][b - 1] = cost[b - 1][a - 1] = t;
        }
        
        res = INF;
		
		for (int i = 0; i < n; i++){
			for (int j = 0; j < n; j++) T[j].son.clear();
			memset(vis, false, sizeof(vis));
			makeTree(i, -1);
			memset(vis, false, sizeof(vis));
			res = min(res, bomb());
		}
		
        printf("%d\n", res);
    }
    
    return (0);
}