现在的位置: 首页 > 综合 > 正文

poj 3107 Godfather (树形dfs)

2012年03月02日 ⁄ 综合 ⁄ 共 2024字 ⁄ 字号 评论关闭

http://poj.org/problem?id=3107 

给定一棵树,取去掉某一节点后形成子树的最大节点数,求使这个数最小的节点。

去掉某一节点后,形成的树包括子树和原树去掉以这个点为根的树所形成的树,在这几个树中求最大值即可。

节点数的计算可用回溯,过程中选取最大值。

貌似是我第一个用邻接表存边的题,贴下模板。

邻接表存边code:

#include<iostream>
#include<cstring>
#include<cstdio>
using namespace std;
const int nMax=1000;
class edge{
    public:
    int v,nex;
};edge e[nMax];
int n,k,head[nMax];      //head[i]是以点i为起点的链表头部
void addedge(int a,int b){//向图中加有向边的算法,注意加上的是有向边
    
//b为a的后续节点既是a---->b
    e[k].v=b;
    e[k].nex=head[a];
    head[a]=k;
    k++;
}
int main(){
    int i,a,b,w,k=1;
    scanf("%d",&n);
    memset(head,0,sizeof(head));
    for(i=0;i<n;i++){
        scanf("%d%d",&a,&b);
        addedge(a,b);                                 //添加一条由a指向b的边
    }
    cin>>w;                                           //输出w点所指向的点
    for(i=head[w];i;i=e[i].nex){
        cout<<e[i].v<<endl;
    }
    cout<<"end\n";
    return 0;} 

code:

#include<cstdio>
#include<cstring>
#include<algorithm>
#define Max(a, b) a>b?a:b
using namespace std ;
const int MAX = 50001 ;
int vis[MAX], head[MAX], ans[MAX], num[MAX] ;
int n, k, Min, sum ;
struct Edge{
    int v, next ;
}edge[2*MAX] ;
void addedge(int a, int b){
    edge[k].v = b ;
    edge[k].next = head[a] ;
    head[a] = k ++ ;
}
void dfs(int x){
    int i, v, min = -1 ;
    num[x] = 1 ;
    vis[x] = 1 ;
    for(i=head[x]; i; i=edge[i].next){
        v = edge[i].v ;
        if(vis[v])  continue ;
        dfs(v) ;
        num[x] += num[v] ;//计算节点数
        min = Max(min, num[v]) ;//选取子树中节点最多的
    }
    min = Max(min, n-num[x]) ;//子树中较大者与除去root为x的树相比较
    if(min<Min){
        Min = min ;
        sum = 1 ;
        ans[0] = x ;
    }else if(min==Min){
        ans[sum++] = x ;
    }
}
int main(){
    int x, y ;
    scanf("%d", &n) ;
    k = 1 ;
    memset(head, 0sizeof(head)) ;
    for(int i=1; i<n; i++){
        scanf("%d%d", &x, &y) ;
        addedge(x, y) ;
        addedge(y, x) ;
    }
    memset(num, 0sizeof(num)) ;
    memset(vis, 0sizeof(vis)) ;
    Min = MAX ;
    dfs(1) ;
    sort(ans, ans+sum) ;
    for(int i=0; i<sum; i++)
        printf("%d ", ans[i]) ;
    printf("\n") ;
    return 0 ;}
【上篇】
【下篇】

抱歉!评论已关闭.