poj3140(树形dp)
这道题是说,给出一棵树,每个节点有一个权值,要求去掉一条边所能获得的两棵树的最小的权值差,其实不能说是dp因为除了最后一步涉及到了取最小之外,其他的地方都是在枚举而已,没有什么状态转移之类的东西存在,只能说是一道简单的树形的搜索
如果你wa了,请检查
1:abs()函数必须要自己写,因为调用的int abs()型的,多以必错无疑
2:是否输入输出的每个地方都已经改成了long long 或者__int64,输入的时候是scanf("%I64d",&a),输出的时候是printf("%i64d",a).我自己的就是某些地方没有全改成这样的输入输出wa了两次
如果你TLE,请用c预言的输入输出,c++的肯定是不行的
1 #include <stdio.h> 2 #include <cstring> 3 using namespace std; 4 5 struct node 6 { 7 int u; 8 int next; 9 }; 10 11 __int64 min(__int64 a , __int64 b ) 12 { 13 return a>b?b:a; 14 } 15 16 node edge[100005*10]; 17 int n,m; 18 __int64 stu[100005]; 19 __int64 all=0; 20 __int64 dp[100005]; 21 __int64 ans; 22 int head[100005]; 23 int visited[100005]; 24 int count; 25 void addEdge(int c , int d) 26 { 27 edge[count].u=d; 28 edge[count].next=head[c]; 29 head[c]=count++; 30 31 edge[count].u=c; 32 edge[count].next=head[d]; 33 head[d]=count++; 34 } 35 36 37 __int64 abs(__int64 a) 38 { 39 return a>0?a:-a; 40 } 41 42 void init() 43 { 44 memset(dp,0,sizeof(dp)); 45 memset(visited,0,sizeof(visited)); 46 all=0; 47 count=0; 48 memset(head,-1,sizeof(head)); 49 memset(edge,0,sizeof(edge)); 50 } 51 52 void dfs(int u) 53 { 54 visited[u]=1; 55 dp[u]=stu[u]; 56 for(int i=head[u];i!=-1;i=edge[i].next)//其中i指的是边,v是边指向的点 57 { 58 int v=edge[i].u; 59 if(visited[v]==0) 60 { 61 dfs(v); 62 dp[u]=dp[u]+dp[v]; 63 } 64 } 65 } 66 int k=1; 67 int main() 68 { 69 while(1) 70 { 71 scanf("%d%d",&n,&m); 72 if(n+m==0) 73 { 74 break; 75 } 76 init(); 77 for(int i=1;i<=n;i++) 78 { 79 scanf("%I64d",&stu[i]); 80 all+=stu[i]; 81 } 82 for(int i=0;i<m;i++) 83 { 84 int a,b; 85 scanf("%d%d",&a,&b); 86 addEdge(a,b); 87 } 88 dfs(1); 89 ans=abs(all-2*dp[1]); 90 for(int i=2;i<=n;i++) 91 { 92 ans=min(ans,abs(all-2*dp[i])); 93 } 94 printf("Case %d: %I64d\n",k++,ans); 95 } 96 return 0; 97 }
就这么多吧