#include
#include
#include
using namespace std;
const int maxn=6000+5;
int val[maxn],vis[maxn];
int dp[maxn][3];
vectorson[maxn];
int dfs(int i){
dp[i][0]=0;
dp[i][1]=val[i];
for(int k=0;k>n;
for(int i=1;i<=n;i++)
cin>>val[i];
int x,y;
for(int i=1;i>x>>y;
vis[x]++;
son[y].push_back(x);
}
for(int i=1;i<=n;i++){
if(!vis[i]){
dfs(i);
cout<
#include
#include
#include
#include
#include
using namespace std;
const int maxn=6000+5;
int val[maxn],vis[maxn];
int dp[maxn][3];
vectorson[maxn];
int dfs(int i){
dp[i][0]=0;
dp[i][1]=1;
for(int k=0;k>n) {
memset(dp,0,sizeof(dp));
memset(vis,0,sizeof(vis));
int x, y;
for (int i = 0; i < n; i++) {
int n1;
scanf("%d:(%d)",&x,&n1);
son[x].clear();
while (n1--) {
cin >> y;
vis[y]++;
son[x].push_back(y);
}
}
for (int i = 0; i < n; i++) {
if (!vis[i]) {
dfs(i);
cout<
错误输入
while(cin>>n) {
memset(dp,0,sizeof(dp));
memset(vis,0,sizeof(vis));
int x, y;
for (int i = 0; i < n; i++) {
cin >> x;
getchar();
getchar();
int n1;
cin >> n1;
getchar();
son[x].clear();
while (n1--) {
cin >> y;
vis[y]++;
son[x].push_back(y);
}
}
for (int i = 0; i < n; i++) {
if (!vis[i]) {
dfs(i);
cout<
正确输入
while(cin>>n) {
memset(dp,0,sizeof(dp));
memset(vis,0,sizeof(vis));
int x, y;
for (int i = 0; i < n; i++) {
int n1;
scanf("%d:(%d)",&x,&n1);
son[x].clear();
while (n1--) {
cin >> y;
vis[y]++;
son[x].push_back(y);
}
}
for (int i = 0; i < n; i++) {
if (!vis[i]) {
dfs(i);
cout<<min(dp[i][0], dp[i][1]) << endl;
}
}
}
#include <iostream>
using namespace std;
#include <vector>
int n;const int maxn=10100;
vector<int>edge[maxn];int f[maxn],dp[maxn];
void dfs(int u,int hui){
f[u]=1;
int maxx=-1;
for(int i=0;i<edge[u].size();i++){
int v=edge[u][i];
if(v==hui)continue;
dfs(v,u);
f[u]+=f[v];
maxx=max(maxx,f[v]);
}
dp[u]=max(maxx,n-f[u]);
}
int main()
{
cin>>n;
int x,y;
int zyx=n/2;
for(int i=1;i<n;i++){
cin>>x>>y;
edge[x].push_back(y);
edge[y].push_back(x);
}
dfs(1,-1);
for(int i=1;i<=n;i++){
if(dp[i]<=zyx){
cout<<i<<endl;
}
}
}
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<vector>
#include<queue>
#include<cmath>
#include<cstring>
using namespace std;
typedef long long ll;
const int MAXN = 10010;
struct Node{
int v, w;
};
vector<Node>edge[MAXN];
int n, m;
ll f[MAXN][2];
void dfs1(int u,int xback){
f[u][0]=0;
for(int i=0;i<edge[u].size();i++) {
int v = edge[u][i].v;
if(v==xback)continue;
dfs1(v,u);
f[u][0]=max(f[u][0],f[v][0]+edge[u][i].w);
}
}
void dfs2(int u,int xback){
int maxx=0,vx,secondmaxx=0,vs;
int flag;
if(u==2||u==3){
flag=1;
}
// cout<
for(int i=0;i<edge[u].size();i++){
int v=edge[u][i].v;
int w=edge[u][i].w;
if(v==xback)continue;
int tmp=f[v][0]+w;
if(tmp>maxx){
//寻找最大的边长f[u][0]
secondmaxx=maxx;vs=vx;//更新第二长secondmaxx
maxx=tmp;vx=v;
// if(flag)cout<
}else if(tmp==maxx||tmp>secondmaxx){
secondmaxx=tmp;vs=v;
// if(flag)cout<
}
}
//寻找到最长边也就是f[u][0]也就是maxx最长的子节点vx=v和第二长secondmaxx
if(u!=1) {//?
int tmp = f[u][1];
int v = -1;
if (tmp > maxx) {
secondmaxx = maxx;
vs = vx;//更新第二长secondmaxx
maxx = tmp;
vx = v;
} else if (tmp == maxx || tmp > secondmaxx) {
secondmaxx = tmp;
vs = v;
}
}
for(int i=0;i<edge[u].size();i++){
int v=edge[u][i].v;
int w=edge[u][i].w;
if(v==xback)continue;
if(v==vx){
f[v][1]=w+secondmaxx;
}
else f[v][1]=w+maxx;
dfs2(v,u);
}
}
int main()
{
int n;
while(cin>>n) {
for (int i = 1; i <= n; i++)edge[i].clear();
int x, y;
for (int i = 2; i <= n; i++) {
cin >> x >> y;
edge[x].push_back((Node) {i, y});
edge[i].push_back((Node) {x, y});
}
dfs1(1, -1);
dfs2(1, -1);
for (int i = 1; i <= n; i++) {
cout << max(f[i][0], f[i][1]) << endl;
}
}
}
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<vector>
#include<queue>
#include<cmath>
#include<cstring>
using namespace std;
typedef long long ll;
//#define a^j (a/2)<
const int MAXN = 50010;
struct Node{
int v, w;
};
vector<Node>edge[MAXN];
int n, m;
ll f[MAXN][2];
ll d[MAXN];
int ma[MAXN][20], mi[MAXN][20];
void dfs1(int u,int xback){
f[u][0]=0;
for(int i=0;i<edge[u].size();i++) {
int v = edge[u][i].v;
if(v==xback)continue;
dfs1(v,u);
f[u][0]=max(f[u][0],f[v][0]+edge[u][i].w);
}
}
void dfs2(int u,int xback){
int maxx=0,vx,secondmaxx=0,vs;
int flag;
if(u==2||u==3){
flag=1;
}
// cout<
for(int i=0;i<edge[u].size();i++){
int v=edge[u][i].v;
int w=edge[u][i].w;
if(v==xback)continue;
int tmp=f[v][0]+w;
if(tmp>maxx){
//寻找最大的边长f[u][0]
secondmaxx=maxx;vs=vx;//更新第二长secondmaxx
maxx=tmp;vx=v;
// if(flag)cout<
}else if(tmp==maxx||tmp>secondmaxx){
secondmaxx=tmp;vs=v;
// if(flag)cout<
}
}
//寻找到最长边也就是f[u][0]也就是maxx最长的子节点vx=v和第二长secondmaxx
if(u!=1) {//?
int tmp = f[u][1];
int v = -1;
if (tmp > maxx) {
secondmaxx = maxx;
vs = vx;//更新第二长secondmaxx
maxx = tmp;
vx = v;
} else if (tmp == maxx || tmp > secondmaxx) {
secondmaxx = tmp;
vs = v;
}
}
for(int i=0;i<edge[u].size();i++){
int v=edge[u][i].v;
int w=edge[u][i].w;
if(v==xback)continue;
if(v==vx){
f[v][1]=w+secondmaxx;
}
else f[v][1]=w+maxx;
dfs2(v,u);
}
}
int logg[MAXN];
int getlog(){
for(int k=1;k<=n;k++) {
logg[k]=0;
while((1<<(logg[k]+1))<=k)logg[k]++;
// int l = 2;
// while (l <= k ) {
// l *= 2;
// logg[k]++;
// }cout<
}
}
void rmq_init(){
for(int i=1;i<=n;i++){
ma[i][0]=mi[i][0]=d[i];
}
for(int j=1;(1<<j)<=n;j++)
for(int i=1;i+(1<<j)-1<=n;i++) {
ma[i][j] = max(ma[i][j - 1], ma[i + (1<<(j - 1))][j - 1]);
mi[i][j] = min(mi[i][j - 1], mi[i + (1<< (j - 1))][j - 1]);
}
getlog();
}
int rmq(int l,int r){
int k=logg[r-l+1];
// cout<
return max(ma[l][k],ma[r-(1 << k)+1][k])-min(mi[l][k],mi[r-(1 << k)+1][k]);
}
int main() {
int query, Q;
while (cin >> n >> query&&!(!n&&!query)) {
for (int i = 1; i <= n; i++)edge[i].clear();
int x, y, z;
for (int i = 1; i < n; i++) {
cin >> x >> y>>z;
edge[x].push_back((Node) {y, z});
edge[y].push_back((Node) {x, z});
}
dfs1(1, -1);
dfs2(1, -1);
for (int i = 1; i <= n; i++) {
d[i] = max(f[i][0], f[i][1]);
}
rmq_init();
while (query--) {
cin >> Q;
int l = 1, maxx = 0;
for (int i = 1; i <= n; i++) {
while (l < i && rmq(l, i) > Q)l++;
maxx = max(maxx, i-l+ 1);
}
cout << maxx << endl;
}
}
}
别人的题解(这个写的真的优秀。可以直接去写p比原来的p的方法简单)https://www.cnblogs.com/gj-Acit/p/4661024.html
#pragma comment(linker, "/STACK:1677721600")
#include <map>
#include <set>
#include <stack>
#include <queue>
#include <cmath>
#include <ctime>
#include <vector>
#include <cstdio>
#include <cctype>
#include <cstring>
#include <cstdlib>
#include <iostream>
#include <algorithm>
using namespace std;
#define INF 0x3f3f3f3f
#define inf (-((LL)1<<40))
#define lson k<<1, L, (L + R)>>1
#define rson k<<1|1, ((L + R)>>1) + 1, R
#define mem0(a) memset(a,0,sizeof(a))
#define mem1(a) memset(a,-1,sizeof(a))
#define mem(a, b) memset(a, b, sizeof(a))
#define FIN freopen("in.txt", "r", stdin)
#define FOUT freopen("out.txt", "w", stdout)
#define rep(i, a, b) for(int i = a; i <= b; i ++)
#define dec(i, a, b) for(int i = a; i >= b; i --)
template<class T> T MAX(T a, T b) { return a > b ? a : b; }
template<class T> T MIN(T a, T b) { return a < b ? a : b; }
template<class T> T GCD(T a, T b) { return b ? GCD(b, a%b) : a; }
template<class T> T LCM(T a, T b) { return a / GCD(a,b) * b; }
//typedef __int64 LL;
typedef long long LL;
const int MAXN = 50000 + 100;
const int MAXM = 110000;
const double eps = 1e-8;
LL MOD = 1000000007;
struct Node {
int v, s;
Node(int _v = 0, int _s = 0) {
v = _v; s = _s;
}
};
vector<Node>G[MAXN];
int mx[MAXN], se[MAXN], d[MAXN], idx[MAXN];
int ma[MAXN][20], mi[MAXN][20];
int n, u, v, w;
int m, Q;
void init(int n) {
rep (i, 0, n) G[i].clear();
mem0(mx); mem0(se);
}
void dfs1(int u, int fa) {
mx[u] = se[u] = 0;
int sz = G[u].size();
rep (i, 0, sz - 1) {
int v = G[u][i].v;
if(v == fa) continue;
dfs1(v, u);
int len = G[u][i].s + mx[v];
if(len > mx[u]) se[u] = mx[u], mx[u] = len;
else if(len > se[u]) se[u] = len;
}
}
void dfs2(int u, int fa, int dis) {
d[u] = max(dis, max(mx[u], se[u]));
int sz = G[u].size();
rep (i, 0, sz - 1) {
int v = G[u][i].v, len = G[u][i].s;
if(v == fa) continue;
if(len + mx[v] == mx[u])
dfs2(v, u, max(dis, se[u]) + len);
else
dfs2(v, u, max(dis, mx[u]) + len);
}
}
void rmq_init(int n) {
rep (i, 1, n) ma[i][0] = mi[i][0] = d[i];
for(int j = 1; (1<<j) <= n; j ++) {
for(int i = 1; i + (1<<j) - 1 <= n; i ++) {
ma[i][j] = max(ma[i][j - 1], ma[i + (1 << (j - 1))][j - 1]);
mi[i][j] = min(mi[i][j - 1], mi[i + (1 << (j - 1))][j - 1]);
}
}
rep (len, 1, n) {
idx[len] = 0;
while((1 << (idx[len] + 1)) <= len) idx[len] ++;
}
}
int rmq(int l, int r) {
int k = idx[r - l + 1];
return max(ma[l][k], ma[r - (1 << k) + 1][k]) - min(mi[l][k], mi[r - (1 << k) + 1][k]);
}
int main()
{
// FIN;
while(~scanf("%d %d", &n, &m) && n) {
init(n);
rep (i, 1, n - 1) {
scanf("%d %d %d", &u, &v, &w);
G[u].push_back(Node(v, w));
G[v].push_back(Node(u, w));
}
//计算每个点到叶子节点的最远距离
dfs1(1, -1);
dfs2(1, -1, 0);
//计算答案
rmq_init(n);
while(m --) {
scanf("%d", &Q);
int l = 1, ans = 0;
rep (i, 1, n) {
while(l < i && rmq(l, i) > Q) l ++;
ans = max(ans, i - l + 1);
}
cout << ans << endl;
}
}
return 0;
}
树形dp总结https://blog.csdn.net/qq_39304630/article/details/81836024
#include <stdio.h>
#include <string.h>
#include <iostream>
#include <algorithm>
#include <vector>
using namespace std;
#define mod 100000000
int n,m;
long long dp[15][1<<12];
bool firhang(int sta){
for(int j=0;j<m;){
if(sta&(1<<j)){
if(j==m-1)return false;
if(sta&(1<<(j+1))){
j+=2;
}
else return false;
}
else j++;
}
return true;
}
//初始航{
//遍历列列举情况
//}
bool check(int now,int pre){
for(int j=0;j<m;) {
if (now & (1 << j)) {
if ((pre & (1 << j))&&j!=m-1&& (pre & (1 << (j + 1))) && (now & (1 << (j + 1)))) {
j += 2;
} else if (!(pre & (1 << j)))j++;
else return false;
} else {
if (pre & (1 << j))j++;
else return false;
}
}
return true;
}
//检查{
//遍历列列举情况
//}
void solve(){
int li=1<<m;
memset(dp,0, sizeof(dp));
for(int s=0;s<li;s++){
if(firhang(s))
dp[1][s]=1;
}
for(int i=2;i<=n;i++){
for(int j=0;j<li;j++)
for(int k=0;k<li;k++){
if(check(j,k))
dp[i][j]+=dp[i-1][k];
}
}
cout<<dp[n][li-1]<<endl;
//遍历2-n行遍历jk行状态。检查增值。
//输出
}
int main()
{
while(cin>>n>>m&&(n||m)){
if((n&1)&&(m&1)){
cout<<0<<endl;
continue;
}
if(n<m){
swap(n,m);
}
solve();
}
return 0;
}
#include <cstring>
#include <cstdio>
#include <iostream>
#include <algorithm>
#include <cmath>
#include <queue>
using namespace std;
int mp[12][12],dp[12][60000];
int n,m;
const int maxn=0x3f3f3f3f;
int arr(int three[],int sum){
int k=0;
for(int i=0;i<n;i++){
three[i]=sum%3;
sum/=3;
if(three[i])k++;
}
// cout<
return k;
}
void init(int li){
for(int i=0;i<n;i++){
for(int j=0;j<li;j++){
dp[i][j]=-1;
}
for(int j=0;j<n;j++){
mp[i][j]=-1;
}
}
}
int main()
{
int a,b,c,in[12],three[12];
in[0]=1;
for(int i=1; i<=10; i++)in[i]=in[i-1]*3;
while(~scanf("%d%d",&n,&m))
{
init(in[n]);
for(int i=0;i<m;i++){
cin>>a>>b>>c;
a--;b--;
if(mp[a][b]==-1){
mp[a][b]=mp[b][a]=c;
}
else{
mp[a][b]=mp[b][a]=min(c,mp[a][b]);
}
}
int li=in[n],flag=-1,minn=maxn;
// cout<
for(int s=1/**/;s<li;s++){
// cout<
int k=arr(three,s);
for(int po=0;po<n;po++){
if(three[po]){
if(k==1){dp[po][s]=0;}
if(dp[po][s]==-1)continue;
if(k==n){flag=0;minn=min(minn,dp[po][s]);}
for(int npo=0;npo<n;npo++){
if(npo!=po&&three[npo]<2&&mp[po][npo]!=-1){
int news=s+in[npo];
if(dp[npo][news]==-1)dp[npo][news]=dp[po][s]+mp[po][npo];
else dp[npo][news]=min(dp[npo][news],dp[po][s]+mp[po][npo]);
// cout<
}
}
}
}
}
if(!flag)cout<<minn<<endl;
else cout<<flag<<endl;
}
return 0;
}
https://blog.csdn.net/txgANG/article/details/72552055