hdu 4714 Tree2cycle dp

2100 단어
나무형 dp로 만든 것으로 dp[t][i]는 t와 그의 아이의 입도가 2보다 작고 t라는 노드의 입도가 i의 최우해임을 나타낸다.
그럼 옮기는 건 자기가 생각해보면 알 수 있을 거야.
관건은 이 문제가 폭발할 수 있다는 것이다. 그래서 나는 bfs로 노드의 순서를 검색한 후에 다시 계산했다.
#include <iostream>
#include <cstdio>
#include <cstring>
using namespace std;
const int maxn=1e6+9;
struct
{
    int to,next;
}e[maxn*2];
int head[maxn],lon;
bool text[maxn];
void edgeini()
{
    memset(head,-1,sizeof(head));
    lon=-1;
}
void edgemake(int from,int to)
{
    e[++lon].to=to;
    e[lon].next=head[from];
    head[from]=lon;
}
int dp[maxn][3];
int from[maxn];
void dfs(int t)
{
    int k;
    int a1=10,a2=10,ret=0,u;
    for(k=head[t];k!=-1;k=e[k].next)
    {
        u=e[k].to;
        if(u==from[t]) continue;
        ret++;
        dp[t][0]+=dp[u][2]+2;
        if(dp[u][1]-dp[u][2]<a1)
        {
            a2=a1;
            a1=dp[u][1]-dp[u][2];
        }
        else if(dp[u][1]-dp[u][2]<a2)
        a2=dp[u][1]-dp[u][2];
    }
    if(ret>=1)
    dp[t][1]=max(0,dp[t][0]+a1-2);
    else
    dp[t][1]=dp[t][0];
    if(ret>=2)
    dp[t][2]=max(0,dp[t][0]+a1+a2-4);
    else
    dp[t][2]=dp[t][1];
//    cout<<0<<endl;
}

int que[maxn];
void bfs()
{
    int front=1,end=0;
    que[++end]=1;
    text[1]=1;
    while(front<=end)
    {
        int t=que[front++];
        for(int k=head[t];k!=-1;k=e[k].next)
        {
            int u=e[k].to;
            if(!text[u])
            {
                from[u]=t;
                text[u]=1;
                que[++end]=u;
            }
        }
    }
    for(int i=end;i>=1;i--)
    dfs(que[i]);
}


int main()
{
    int T;
    scanf("%d",&T);
    while(T--)
    {
        memset(dp,0,sizeof(dp));
        edgeini();
        int n;
        scanf("%d",&n);
        for(int i=1,from,to;i<n;i++)
        {
            scanf("%d %d",&from,&to);
            edgemake(from,to);
            edgemake(to,from);
        }
        memset(text,0,sizeof(text));
        bfs();
        printf("%d
",dp[1][2]+1); } return 0; }

좋은 웹페이지 즐겨찾기