bzoj1487 无归岛

  无归岛

题目背景:

bzoj1487

分析:仙人掌DP (?) 树型DP(?)

 

懵圈的DP +1···这个题的题目大意大概就是,每一个岛都是一个环,然后这些环存在一些公共的顶点,使环与环之间是连在一起的(有一个顶点相连),具体可以画一下样例你就懂了,然后选择不相邻的点来使权值最大,首先我们来分析下这道题,因为不存在环套环的情况,那不是很清真吗,对于每一个环,我们确定一个顶点,然后从这个顶点开始dp,定义状态f[i][0/1]表示这个顶点选择或者不选择,若选择了则为1状态,那么两边的状态一定为0状态,若没有选择,则两边的状态随意即可。

具体实现:dfs的时候记录dfs序,若当前顶点cur为一个环的顶点,那么一定存在一个与之相连的点x满足x的父亲不是cur,并且它的dfs序大于curdfs序,那么我们处理掉这个环即可

Source

/*
	created by scarlyw
*/
#include <iostream>
#include <cstdio>
#include <string>
#include <cstring>
#include <cmath>
#include <algorithm>
#include <cctype>
#include <set>
#include <map>
#include <vector>
#include <queue>

const int MAXN = 100000 + 10;

int n, m, x, y, ind;
int num[MAXN], a[MAXN], f[MAXN][2], father[MAXN];
std::vector<int> edge[MAXN];

inline void add_edge(int x, int y) {
	edge[x].push_back(y), edge[y].push_back(x);
}

inline void read_in() {
	scanf("%d%d", &n, &m);
	for (int i = 1; i <= m; ++i) scanf("%d%d", &x, &y), add_edge(x, y);
	for (int i = 1; i <= n; ++i) scanf("%d", &a[i]);
}

inline void solve(int x, int y) {
	int now0 = 0, now1 = 0, t1, t0;
	for (int i = y; i != x; i = father[i]) {
		t1 = f[i][0] + now0, t0 = f[i][1] + now1;
		now0 = std::max(t1, t0), now1 = t1;
	}
	f[x][0] += now0, now0 = 0, now1 = -1000000000;
	for (int i = y; i != x; i = father[i]) {
		t1 = f[i][0] + now0, t0 = f[i][1] + now1;
		now0 = std::max(t1, t0), now1 = t1;
	}
	f[x][1] += now1;
}

inline void dfs(int cur) {
	num[cur] = ++ind;
	for (int p = 0; p < edge[cur].size(); ++p) {
		int v = edge[cur][p];
		if (num[v] == 0) father[v] = cur, dfs(v);
	}
	f[cur][1] = a[cur];
	for (int p = 0; p < edge[cur].size(); ++p) {
		int v = edge[cur][p];
		if (father[v] != cur && num[v] > num[cur]) solve(cur, v);
	}
}

inline void solve() {
	read_in();
	dfs(1), printf("%d", std::max(f[1][0], f[1][1]));
}

int main() {
	solve();
	return 0;
}

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值