需要强调点是基环树可能是个森林。
1.对一个n点n边的图找出任意两点不想连的最大全值,相当于最大权独立集:
dps找到环的位置,然后求得环中某个位置点头u和尾v,分别按树跑一次dp,max(dp[u][0],dp[v][0])就是最大值
因为v与u必定不要一个,求不要其中一个的最大值就是结果
#include<bits/stdc++.h>
using namespace std;
const int maxn=1e5+7;
const int N = 1e6+10; //基环树中点的个数
const int E = 1e6+10; //基环树中无向边的个数
struct Edge{int next,to;}e[E*2];
int head[N], cnt;
bool vis[N];
int val[N], ringPt1, ringPt2, not_pass; //ringPt1,ringPt2 -> not_pass边的端点
long long dp[2][N];
void add(int u,int v){
e[++cnt].next = head[u];
e[cnt].to = v;
head[u] = cnt;
}
void getDP(int rt, int fa) {
dp[0][rt] = 0, dp[1][rt] = val[rt];
for(int i=head[rt];i!=-1;i=e[i].next) {
if(e[i].to == fa) continue;
if(i == not_pass || i == (not_pass^1)) continue;
getDP(e[i].to, rt);
//