CF-1332 F. 독립 설정

F. 독립 설정

문제의 의미

n 개의 노드가 트리 각 판정 (에지 - 유도 ~ 서브 그래프 \ \ ) 세트와 독립적 수.

\ (에지 - 유도 ~ 서브 그래프 \ ) 에 대한 에지들의 세트 것을 의미 \ (E (E '\ 부분 E) \) , \ (E \) 의 모든 포인트가 서브 그래프에있다.

제목에 원하는 결과를 주목하는 것은, E '는 비워 둘 수 없습니다

분석

먼저 차기 서브 그래프, 숲에서 어떤 점에서 선택에 대한 문제는 그들이 아니라 각면을 그래서 필요한 설정 값의 수. 나무의 문제를 들어, 나무는 DP로 결정할 수있다

집합 \ (d [X] [0 ] \) 의 수 X가 선택되지 않은 프로그램을 나타내는 \ (D를 [X]는 [. 1] \) 프로그램의 수를 나타내는 X 선택한

그때

\ (d [X] [0] = \ 자극 (d [Y] [1] + D [Y] [0]) \\ D [X] [1] = \ 프로드 D [Y] [0] \)

그러나이 질문은 나무에서 x와 y에 필요는 없다 그래서 또한 고려 (\ X \ 우측으로 향하는 화살표 Y) \ 상태의 측면에.

  1. 서브 그래프의 에지는 상기 상태 (X)의 상태는 Y는 연관된

  2. 에지 서브 그래프는 X와 Y 상태의 상태가 관련이있는 것이 아니다

전환 방정식이있다,이 두 가지 상태를 고려 :

\ (d [X] [0] = \ 자극 2 * (d [Y] [1] D + [Y] [0]) \)

\ (d [X] [1] = \ 자극 (d [Y] [0] + D [Y] [1] D + [Y] [0]) \)

여기 문제가 해결 될 것 같지만 차트의 부제는 구조의 측면에 의해 설정되어 있기 때문에 노트에 "스팟"이 상황은 지금이 상황을 없애 간주, 허용되지 않음.

집합 \ (F [X]는 \) 프로그램의 수는 서브 - 수치 (X) 및 모든 자식 노드에 결합되는 Y 측에 있지 나타낸다

때와 (F [Y] \) \ 때 업데이트 (X)에, 경우 \ (\ X \은 우측으로 향하는 화살표 Y) 이 에지가 선택되어 있지 않은 경우, Y 선택 상태 \ (d [Y] [1 ] \) 에 저장해야 이동 \ (F [Y] \) 다음과 같은 예를 나타내고,이 전송되는 하나의 점으로서 선택 될 수 없다 :

\ [X] [0] = \ 자극 (d [Y] [1] + D [Y] [0]) + (d [Y] [1] -f [Y] + D를 {예} D를 시작 \ [Y] [0]) \\ D [X] [1] = \ 자극 (d [Y] [0]) + (d [Y] [1] - F [Y] D + [Y] [0] \\) F [X] = \ 자극 (d [Y] [1] -f [Y] D + [Y] [0]) \ {단부 경우} \]

최종 응답이 \ (D [1] [0] + D [1] [1] -f [1] -1 \) , 1 감산 최종적으로도 10의 블랭크를 감산된다.

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int inf = 0x3f3f3f3f;
#define dbg(x...) do { cout << "\033[32;1m" << #x <<" -> "; err(x); } while (0)
void err() { cout << "\033[39;0m" << endl; }
template<class T, class... Ts> void err(const T& arg,const Ts&... args) { cout << arg << " "; err(args...); }
const int N = 300000 + 5;
const int mod = 998244353;
int head[N], ver[N<<1], nxt[N<<1], tot;
int n;
ll d[N][2], f[N];
void add(int x, int y){
    ver[++tot] = y, nxt[tot] = head[x], head[x] = tot;
}
void dfs(int x, int fa){
    d[x][0] = d[x][1] = f[x] = 1;
    for(int i=head[x];i;i=nxt[i]){
        int y = ver[i];
        if(y == fa) continue;
        dfs(y, x);
        d[x][0] = d[x][0] * ((2 * d[y][0] + 2 * d[y][1] - f[y])%mod) % mod;
        d[x][1] = d[x][1] * ((2 * d[y][0] + d[y][1] - f[y]) % mod) % mod;
        f[x] = f[x] * ((d[y][0] + d[y][1] - f[y]) % mod) % mod;
    }
     dbg(x, d[x][0], d[x][1], f[x]);
}
int main(){
    scanf("%d", &n);
    for(int i=2;i<=n;i++){
        int x, y;
        scanf("%d%d", &x, &y);
        add(x, y);
        add(y, x);
    }
    dfs(1, 0);
    cout << (d[1][0] + d[1][1] - f[1] - 1 + 2 * mod) % mod;
    return 0;
}

이 문제는 코드를 작성하는 것은 매우 쉽습니다, 키가 DP 전송을 찾는 것입니다, CF는 아주 명확한 주제를 설명하고, 이러한 힌트 감사가 발생할 수 있습니다 경주에 배치하면 샘플 다시는 설명

추천

출처www.cnblogs.com/1625--H/p/12655281.html