hdu 4274 2012长春赛区网络赛 树形dp ***
设定每个节点的上限和下限,之后向上更新,判断是否出现矛盾
1 #include<cstdio> 2 #include<iostream> 3 #include<algorithm> 4 #include<cstring> 5 #include<cmath> 6 #include<queue> 7 #include<map> 8 using namespace std; 9 #define MOD 1000000007 10 const int INF=1000010; 11 const double eps=1e-5; 12 typedef long long ll; 13 #define cl(a) memset(a,0,sizeof(a)) 14 #define ts printf("*****\n"); 15 const int N=10005; 16 int n,m,tt,tot=0,head[N],dp[N]; 17 int maxw; 18 bool flag; 19 struct edge 20 { 21 int to,next; 22 }edge[N*2]; 23 int up[N],low[N]; 24 void addedge(int a,int b) 25 { 26 edge[tot].to=a; 27 edge[tot].next=head[b]; 28 head[b]=tot++; 29 } 30 void init() 31 { 32 memset(head,-1,sizeof(head)); 33 tot=0; 34 } 35 void dfs(int u,int pre) 36 { 37 if(flag) return; 38 if(up[u]!=-1&&low[u]>up[u]) 39 { 40 flag=1; 41 return; 42 } 43 int le=0; 44 int sum=0; 45 for(int i=head[u];i!=-1;i=edge[i].next) 46 { 47 int v=edge[i].to; 48 if(v==pre) continue; 49 le=1; 50 dfs(v,u); 51 sum+=low[v]; 52 } 53 if(!le) return; 54 low[u]=max(sum+1,low[u]); 55 if(up[u]!=-1&&low[u]>up[u]) 56 { 57 flag=1; 58 return; 59 } 60 } 61 int main() 62 { 63 int i,j,k; 64 #ifndef ONLINE_JUDGE 65 freopen("1.in","r",stdin); 66 #endif 67 while(scanf("%d",&n)!=EOF) 68 { 69 init(); 70 for(i=2;i<=n;i++) 71 { 72 int u; 73 scanf("%d",&u); 74 addedge(i,u); 75 addedge(u,i); 76 } 77 for(i=1;i<=n;i++) up[i]=-1,low[i]=1; 78 scanf("%d",&m); 79 for(i=0;i<m;i++) 80 { 81 int u,v,w; 82 char c[10]; 83 scanf("%d%s%d",&u,c,&w); 84 if(c[0]=='<') up[u]=w-1; 85 else if(c[0]=='>') low[u]=w+1; 86 else low[u]=up[u]=w; 87 } 88 flag=0; 89 dfs(1,-1); 90 if(flag) 91 { 92 printf("Lie\n"); 93 } 94 else printf("True\n"); 95 } 96 }