Pagini recente » Cod sursa (job #1215242) | Cod sursa (job #1658788) | Cod sursa (job #157405) | Statisticile problemei Brasov | Cod sursa (job #1708369)
Utilizator |
Stefan Ruseti stefanr |
Data |
26 mai 2016 22:51:14 |
Problema |
Revolta |
Scor |
Ascuns |
Compilator |
cpp |
Status |
done |
Runda |
|
Marime |
5.58 kb |
/*
* File: brute.cpp
* Author: Stefan
*
* Created on May 23, 2016, 11:48 PM
*/
#include <cstdlib>
#include <iostream>
#include <vector>
using namespace std;
#define INF 100000000
#define NMAX 10000
int n;
vector< vector<int> > graph;
vector<int> dhl;
vector<int> dl;
vector<bool> visited;
int removedFirst, removedSecond;
int addedFirst, addedSecond;
bool removed(int a, int b) {
if (removedFirst == -1) return false;
return (a == removedFirst && b == removedSecond) ||
(b == removedFirst && a == removedSecond);
}
int computeDepth(int node) {
visited[node] = true;
dhl[node] = 0;
for (vector<int>::iterator next = graph[node].begin(); next < graph[node].end(); next++) {
if (!visited[*next] && !removed(node, *next)) {
int d = computeDepth(*next);
if (dhl[node] < d) dhl[node] = d;
}
}
dhl[node] ++;
return dhl[node];
}
int moveRoot(int node) {
int a = 0;
int b = 0;
int longest = -1;
for (vector<int>::iterator next = graph[node].begin(); next < graph[node].end(); next++) {
if (!removed(node, *next)) {
int d = dhl[*next];
if (d > a) {
b = a;
a = d;
longest = *next;
}
else
if (d > b) b = d;
}
}
//cout << a << " " << b << " " << longest << endl;
if (longest == -1 || a - b <= 1) return node;
dhl[node] = b + 1;
return moveRoot(longest);
}
void dfs(int node) {
int maxDepth1 = 0, maxDepth2 = 0;
int maxDiam1 = 0, maxDiam2 = 0;
visited[node] = true;
for (int i = 0; i < graph[node].size(); i++) {
int next = graph[node][i];
if (!visited[next] && !removed(node, next)) {
dfs(next);
if (dhl[next] > maxDepth1) {
maxDepth2 = maxDepth1;
maxDepth1 = dhl[next];
}
else {
if (dhl[next] > maxDepth2) {
maxDepth2 = dhl[next];
}
}
if (dl[next] > maxDiam1) {
maxDiam2 = maxDiam1;
maxDiam1 = dl[next];
}
else {
if (dl[next] > maxDiam2) {
maxDiam2 = dl[next];
}
}
}
}
dhl[node] = maxDepth1 + 1;
dl[node] = max(maxDiam1, maxDepth1 + maxDepth2);
}
int diameter() {
visited.assign(n, false);
dhl.assign(n, 0);
dl.assign(n, 0);
dfs(0);
for (int i = 0; i < n; i++)
if (!visited[i]) return -1;
return dl[0];
}
void clear() {
graph.clear();
dhl.clear();
dl.clear();
visited.clear();
}
vector< pair<int,int> > getEdges() {
vector< pair<int,int> > result;
for (int i = 0; i < n - 1; i ++) {
for (vector<int>::iterator next = graph[i].begin(); next < graph[i].end(); next++) {
if (i > *next) continue;
result.push_back(pair<int, int>(i, *next));
}
}
return result;
}
vector< pair<int,int> > getInexistentEdges() {
vector< pair<int,int> > result;
vector<bool> exists(n, false);
for (int i = 0; i < n - 1; i ++) {
exists.assign(n, false);
for (vector<int>::iterator next = graph[i].begin(); next < graph[i].end(); next++) {
exists[*next] = true;
}
for (int j = i + 1; j < n; j++)
if (!exists[j])
result.push_back(pair<int, int>(i, j));
}
return result;
}
bool better(int *best, int *guess) {
for (int i = 0; i < 4; i++) {
if (guess[i] == best[i]) continue;
return guess[i] < best[i];
}
return false;
}
/*
*
*/
int main(int argc, char** argv) {
freopen ("revolta.in","r",stdin);
freopen ("revolta.out","w",stdout);
int t;
scanf("%d", &t);
while (t-- > 0) {
scanf("%d", &n);
graph.assign(n, vector<int>());
dl.assign(n, -1);
dhl.assign(n, -1);
removedFirst = -1;
int a, b;
for (int i = 0; i < n - 1; i++) {
scanf("%d &d", &a, &b);
graph[a].push_back(b);
graph[b].push_back(a);
}
int initialDiameter = diameter();
vector< pair<int,int> > edges = getEdges();
vector< pair<int,int> > possibleEdges = getInexistentEdges();
int best = n;
int bestSoFar[4];
int guess[4];
for (int i = 0; i < edges.size(); i++) {
removedFirst = edges[i].first;
removedSecond = edges[i].second;
for (int j = 0; j < possibleEdges.size(); j++) {
pair<int, int> e = possibleEdges[j];
graph[e.first].push_back(e.second);
graph[e.second].push_back(e.first);
int d = diameter();
graph[e.first].pop_back();
graph[e.second].pop_back();
if (d == -1) continue; //not a tree
guess[0] = e.first;
guess[1] = e.second;
guess[2] = removedFirst;
guess[3] = removedSecond;
if ((d == best && better(bestSoFar, guess)) || d < best) {
for (int g = 0; g < 4; g++) {
bestSoFar[g] = guess[g];
}
best = d;
}
}
}
if (initialDiameter <= best) cout << initialDiameter << endl;
else {
cout << best << endl;
//cout << bestSoFar[2] << " " << bestSoFar[3] << endl;
//cout << bestSoFar[0] << " " << bestSoFar[1] << endl;
}
clear();
}
return 0;
}