/* **********************************************
File Name: 1520.cpp
Auther: [email protected]
Created Time: 2015年08月18日 星期二 19时50分55秒
*********************************************** */
#include
using namespace std;
const int INF = 0xfffffff;
const int MAX = 6007;
vector<int> G[MAX];
int val[MAX];
int dp[2][MAX];
bool vis[MAX];
int n;
void dfs(int u) {
//printf("dfs %d\n", u);
vis[u] = true;
dp[0][u] = 0;
dp[1][u] = val[u];
for (auto it = G[u].begin(); it != G[u].end(); ++it) {
if (!vis[*it]) {
dfs(*it);
dp[1][u] += max(0, dp[0][*it]);
dp[0][u] += max(0, max(dp[0][*it], dp[1][*it]));
}
}
}
int main() {
while (cin >> n && n) {
for (int i = 1; i <= n; ++i) {
G[i].clear();
cin >> val[i];
}
int x, y;
for (int i = 1; i < n; ++i) {
cin >> x >> y;
G[x].push_back(y);
G[y].push_back(x);
}
cin >> x >> y; //0 0
//fill(dp[0], dp[0] + n + 1, -INF);
//fill(dp[1], dp[1] + n + 1, -INF);
memset(vis, false, sizeof(vis));
dfs(1); //node 1 is root
/*
for (int i = 1; i <= n; ++i) {
printf("dp[0][%d] = %d, dp[1][%d] = %d\n", i, dp[0][i], i, dp[1][i]);
}
*/
int ans = max(dp[0][1], dp[1][1]);
if (ans == 0) {
ans = -INF;
for (int i = 1; i <= n; ++i) {
if (ans < val[i]) {
ans = val[i];
}
}
}
cout << ans << endl;
}
return 0;
}
/* **********************************************
File Name: 2196.cpp
Auther: zhengdongjian@tju.edu.cn
Created Time: 2015年08月19日 星期三 08时35分06秒
*********************************************** */
#include
using namespace std;
/*
* let dp[i][j]表示节点i的孩纸j所在子树的最大深度.
* dp[i][j] = max{dp[j][k]} + 1.
* Then. dfs后继遍历整棵树,父亲为root,遍历孩纸i时,
* 传递max{max{dp[root][k]}(k!=i), fd}和一个深度标记。
* 其中fd为root的父亲传递进来的值。深度标记需要修正。
* 此次扫描即可得出每个点的花费
*/
typedef pair P;
typedef pair PP;
const int MAX = 10007;
vector
G[MAX];
multimap
M[MAX];
int cost[MAX];
bool vis[MAX];
int dfs(int u) {
vis[u] = true;
int res = 0;
for (auto it = G[u].begin(); it != G[u].end(); ++it) {
if (!vis[it->first]) {
int dep = dfs(it->first) + it->second;
if (dep > res) res = dep;
M[u].insert(PP(P(dep, it->first), it->second));
}
}
return res;
}
void gao(int u, int fd) {
//printf("gao %d, with %d\n", u, fd);
//cost[u] = max{fd, M[u].rbegin()->first|M[u].rbegin()-1 ->first}
cost[u] = max(fd, M[u].empty() ? 0 : M[u].rbegin()->first.first);
//printf("cost[%d] = %d\n", u, cost[u]);
if (M[u].empty()) {
return;
} else if (M[u].size() == 1) {
auto it = M[u].begin();
gao(it->first.second, it->second + fd);
} else {
for (auto it = M[u].begin(); it != M[u].end(); ++it) {
for (auto it2 = M[u].rbegin(); it2 != M[u].rend(); ++it2) {
if (it2->first.second != it->first.second) {
//printf("%d != %d\n", it2->first.second, it->first.second);
gao(it->first.second, it->second + max(fd, it2->first.first));
break;
}
}
}
}
}
int main() {
int n;
while (cin >> n) {
for (int i = 1; i <= n; ++i) {
G[i].clear();
M[i].clear();
}
int x, y;
for (int i = 2; i <= n; ++i) {
cin >> x >> y;
G[i].push_back(P(x, y));
G[x].push_back(P(i, y));
}
memset(vis, false, sizeof(vis));
dfs(1);
/*
for (int i = 1; i <= n; ++i) {
printf("%d: ", i);
for (auto it = M[i].begin(); it != M[i].end(); ++it) {
printf("<%d,%d> ", it->first.second, it->first.first);
}
puts("");
}
*/
gao(1, 0);
for (int i = 1; i <= n; ++i) {
printf("%d\n", cost[i]);
}
}
return 0;
}
发现2
可知不会有其它点指向环上任意一点,那么只需要考虑有向外指向的边,这很好处理,我们只需要 check 一下,任何能从该环开始扫描到的点都视为 invalid ,不合法。单向环
上或者由某一个单向环
可达的点检查出来,后续处理忽视它们即可。只选择根节点
的收益 v2=sum+1 一定大于 v1 ,所以 M+1 个点中一定有一个时根节点。把得到的最终方案中,根节点剔除掉,显然便是正解。而且输入数据对没有依赖的点给出的 a=0 也为这么做提供了方便/* **********************************************
File Name: 1561.cpp
Auther: [email protected]
Created Time: 2015年08月19日 星期三 10时59分42秒
*********************************************** */
#include
using namespace std;
const int MAX = 207;
const int INF = INT_MAX / MAX;
vector<int> G[MAX];
int val[MAX];
bool vis[MAX];
bool valid[MAX];
int dp[MAX][MAX];
int dp2[MAX];
int n, m;
void check(int u) {
vis[u] = true;
for (auto it = G[u].begin(); it != G[u].end(); ++it) {
if (vis[*it]) {
valid[u] = false;
}
check(*it);
if (!valid[*it]) valid[u] = false;
}
}
/*
* dp[i][j]: 以节点i为根(必选i)的j个城堡的最大收益.
* dp[i][0] = 0;
*/
void dfs(int u) {
dp[u][0] = 0;
if (!valid[u]) {
return;
}
dp[u][1] = val[u];
for (auto it = G[u].begin(); it != G[u].end(); ++it) {
dfs(*it);
memcpy(dp2, dp[u], sizeof(int) * MAX);
for (int j = 2; j <= m + 1; ++j) {
//printf("check %d\n", j);
for (int k = 1; k < j; ++k) {
dp2[j] = max(dp2[j], dp[*it][k] + dp[u][j - k]);
}
}
memcpy(dp[u], dp2, sizeof(int) * MAX);
}
}
int main() {
while (cin >> n >> m && n) {
for (int i = 0; i <= n; ++i) {
G[i].clear();
}
int a, sum = 0;
for (int i = 1; i <= n; ++i) {
cin >> a >> val[i];
G[a].push_back(i);
sum += val[i];
}
val[0] = sum + 1;
memset(valid, true, sizeof(valid));
memset(vis, false, sizeof(vis));
check(0);
for (int i = 0; i <= n; ++i) {
fill(dp[i], dp[i] + m + 2, -INF);
}
dfs(0);
printf("%d\n", dp[0][m + 1] - sum - 1);
}
return 0;
}
/* **********************************************
File Name: 3534.cpp
Auther: zhengdongjian@tju.edu.cn
Created Time: 2015年08月19日 星期三 13时59分25秒
*********************************************** */
#include
using namespace std;
typedef long long ll;
const int MAX = 10007;
struct Edge {
int to;
ll dis;
Edge(int to = 0, int dis = 0): to(to), dis(dis) {}
};
vector G[MAX];
map M[MAX];
ll dis[MAX][2];
ll longest;
int ans;
bool vis[MAX];
void dfs(int u) {
vis[u] = true;
for (auto it = G[u].begin(); it != G[u].end(); ++it) {
if (!vis[it->to]) {
dfs(it->to);
if (dis[u][0] < dis[it->to][0] + it->dis) {
dis[u][1] = dis[u][0];
dis[u][0] = dis[it->to][0] + it->dis;
} else if (dis[u][1] < dis[it->to][0] + it->dis) {
dis[u][1] = dis[it->to][0] + it->dis;
}
}
}
if (dis[u][0] + dis[u][1] > longest) {
longest = dis[u][0] + dis[u][1];
}
}
void dfs2(int u) {
vis[u] = true;
for (auto it = G[u].begin(); it != G[u].end(); ++it) {
if (!vis[it->to]) {
dfs2(it->to);
int dis1 = M[it->to].rbegin()->first + it->dis;
if (M[u].find(longest - dis1) != M[u].end()) {
ans += M[u].find(longest - dis1)->second * M[it->to].rbegin()->second;
}
M[u][it->dis + M[it->to].rbegin()->first] += M[it->to].rbegin()->second;
//printf("M[%d][%lld] += %d\n", u, it->dis + M[it->to].rbegin()->first, M[it->to].rbegin()->second);
}
}
if (M[u].empty()) {
M[u][0]++;
}
}
int main() {
ios::sync_with_stdio(false);
int n;
while (cin >> n) {
for (int i = 1; i <= n; ++i) {
G[i].clear();
M[i].clear();
}
int u, v, len;
for (int i = 1; i < n; ++i) {
cin >> u >> v >> len;
G[u].push_back(Edge(v, len));
G[v].push_back(Edge(u, len));
}
memset(vis, false, sizeof(vis));
memset(dis, 0, sizeof(dis));
longest = 0LL;
dfs(1);
/*
for (int i = 1; i <= n; ++i) {
printf("dis[%d] = <%lld, %lld>\n", i, dis[i][0], dis[i][1]);
}
*/
//cout << "longest = " << longest << endl;
memset(vis, false, sizeof(vis));
ans = 0;
dfs2(1);
if (M[1].find(longest) != M[1].end()) {
ans += M[1].find(longest)->second;
}
cout << longest << ' ' << ans << endl;
}
return 0;
}