1. 程式人生 > >uva1218 Perfect Service

uva1218 Perfect Service

inf main 遍歷 ont struct 計算 == 服務器 div

題目大意:

有n(n10000)臺機器形成樹形結構。要求在其中一些機器上安裝服務器,使得每臺不是服務器的計算機恰好和一臺服務器計算機相鄰。求服務器的最少數量。

/*
    遞歸時分為3種情況
    0表示,u為服務器,那麽他的所有子節點可以為服務器也可以不為服務器
    res+=min(dp[v][0],dp[v][1]);
    1表示,u不為服務器,但是u的父節點為服務器,那麽所有子節點都不能為服務器
    res=sum(dp[v][2]);
    2表示,u不為服務器,且u的父親也不為服務器,那麽u的子節點中只有一個為服務器,別的都不為服務器
    dp[u][2]可以根據dp[u][1]遍歷一次推得,dp[u][2]=min(dp[u][2],dp[u][1]-dp[v][2]+dp[v][0])
*/ #include<iostream> #include<cstdio> #include<cstring> using namespace std; #define maxn 10010 #define INF 10010 int n,dp[maxn][3],num,head[maxn]; struct node{ int to,pre; }e[maxn*2]; void Insert(int from,int to){ e[++num].to=to; e[num].pre=head[from]; head[
from]=num; } int f(int now,int fa,int sta){ if(dp[now][sta]!=-1)return dp[now][sta]; int res=0; if(sta==0){ res=INF; int cnt=0; for(int i=head[now];i;i=e[i].pre){ int to=e[i].to;cnt++; if(to==fa)continue; res=min(res,f(to,now,1
)); } if(cnt==1&&fa!=-1)res=INF; } if(sta==1){ for(int i=head[now];i;i=e[i].pre){ int to=e[i].to; if(to==fa)continue; res+=min(f(to,now,1),f(to,now,2)); } res++; } if(sta==2){ for(int i=head[now];i;i=e[i].pre){ int to=e[i].to; if(to==fa)continue; res+=f(to,now,0); } } dp[now][sta]=res; return res; } int main(){ //freopen("Cola.txt","r",stdin); while(1){ memset(dp,-1,sizeof(dp)); memset(head,0,sizeof(head)); memset(e,0,sizeof(e)); num=0; scanf("%d",&n); int x,y; for(int i=1;i<n;i++){ scanf("%d%d",&x,&y); Insert(x,y); Insert(y,x); } printf("%d\n",min(f(1,-1,0),f(1,-1,1))); int t; scanf("%d",&t); if(t==-1)return 0; } }

uva1218 Perfect Service