UVA 12452
来源:互联网 发布:金蝶数据库修复工具 编辑:程序博客网 时间:2024/06/08 18:22
简单树形DP
昨天做这道题一直RE,最后在队友帮助下手写栈过了
今天再看昨天的代码,发现自己确实写搓了,在每次dfs中都要开10000的数组不爆才怪.....换种写法就可以了
代码能力太渣没办法,继续加油!
#include<iostream>#include<cstring>#include<cstdio>#include<algorithm>#include<cmath>#include<stack>#include<queue>#include<vector>#include<map>#include<ctime>#include<set>#include<string>#define N 20010using namespace std;struct Edge{ int v,next;}edge[N*2];int head[N];int n,cnt;int dp[N][2];void init(){ memset(head,-1,sizeof(head)); memset(dp,0,sizeof(dp)); cnt=0;}void addedge(int u,int v){ edge[cnt].v=v; edge[cnt].next=head[u]; head[u]=cnt++; edge[cnt].v=u; edge[cnt].next=head[v]; head[v]=cnt++;}void dfs(int u,int fa){ int sum=0; int ans1=0,ans2=0; int a[2],j=0; a[0]=a[1]=1000000000; for(int i=head[u];i!=-1;i=edge[i].next){ int v=edge[i].v; if(v==fa)continue; sum++; dfs(v,u); ans1+=dp[v][0]; ans2+=dp[v][1]; if(a[0]>dp[v][0]-dp[v][1]){ a[1]=a[0]; a[0]=dp[v][0]-dp[v][1]; } else if(a[1]>dp[v][0]-dp[v][1]) a[1]=dp[v][0]-dp[v][1]; } if(sum==0){ dp[u][0]=0; dp[u][1]=100; return ; } dp[u][0]=ans2; dp[u][0]=min(dp[u][0],ans1+500); //all cover dp[u][0]=min(dp[u][0],ans2+a[0]+100); //cover 1 if(sum>1) dp[u][0]=min(dp[u][0],ans2+a[0]+a[1]+175); //cover 2 if(fa==-1)return; dp[u][1]=ans2+100; dp[u][1]=min(dp[u][1],ans1+500); //all cover dp[u][1]=min(dp[u][1],ans2+a[0]+175);}int main(){ int t,T,u,v,i; scanf("%d",&T); for(t=1;t<=T;t++){ scanf("%d",&n); init(); for(i=0;i<n-1;i++){ scanf("%d %d",&u,&v); addedge(u,v); } dfs(0,-1); printf("$%d\n",dp[0][0]); } return 0;}
手写栈的版本
//#pragma comment(linker,"/STACK:1024000000,1024000000")#include <cstdio>#include <cstring>#include <algorithm>#include<stack>#define N 100010using namespace std;struct Edge{ int v,next;}edge[N*2];int head[N];int n,cnt;int dp[N][2];void init(){ memset(head,-1,sizeof(head)); memset(dp,0,sizeof(dp)); cnt=0;}void addedge(int u,int v){ edge[cnt].v=v; edge[cnt].next=head[u]; head[u]=cnt++; edge[cnt].v=u; edge[cnt].next=head[v]; head[v]=cnt++;}void dfs(){ stack<pair<int, int> > sta; sta.push(make_pair(0, -1)); //******* bool vis[N]; memset(vis,0,sizeof(vis)); while (!sta.empty()){ //******* int u = sta.top().first, fa = sta.top().second; //******* if(vis[u]==0){ //******* for(int i=head[u];i!=-1;i=edge[i].next){ int v=edge[i].v; if(v==fa)continue; sta.push(make_pair(v, u)); //******* } vis[u]=1; //******* } if (u != sta.top().first) //******* continue; sta.pop(); //******* int sum=0; int ans1=0,ans2=0; for(int i=head[u];i!=-1;i=edge[i].next){ int v=edge[i].v; if(v==fa)continue; sum++; ans1+=dp[v][0]; ans2+=dp[v][1]; } if(sum==0){ dp[u][0]=0; dp[u][1]=100; continue ; } dp[u][0]=ans2; if(sum==1) dp[u][0]=min(dp[u][0],ans1+100); else if(sum==2) dp[u][0]=min(dp[u][0],ans1+175); else dp[u][0]=min(dp[u][0],ans1+500); //all cover int a[N],j=0; if(sum>1){ for(int i=head[u];i!=-1;i=edge[i].next){ int v=edge[i].v; if(v==fa)continue; a[j++]=dp[v][0]-dp[v][1]; } sort(a,a+j); dp[u][0]=min(dp[u][0],ans2+a[0]+100); //cover 1 if(sum>2) dp[u][0]=min(dp[u][0],ans2+a[0]+a[1]+175); //cover 2 } if(fa==-1)continue; dp[u][1]=ans2+100; if(sum==1) dp[u][1]=min(dp[u][1],ans1+175); else dp[u][1]=min(dp[u][1],ans1+500); //all cover if(sum>1){ dp[u][1]=min(dp[u][1],ans2+a[0]+175); } }}int main(){ int t,T,u,v,i; scanf("%d",&T); for(t=1;t<=T;t++){ scanf("%d",&n); init(); for(i=0;i<n-1;i++){ scanf("%d %d",&u,&v); addedge(u,v); } dfs(); printf("$%d\n",dp[0][0]); } return 0;}
- UVA 12452
- uva
- UVA
- UVA
- UVA
- uva
- UVA
- UVA
- UVA
- UVA
- UVA
- UVA
- UVA
- UVA
- UVA
- UVA
- UVA
- UVA
- Margin还是Padding?这是个问题。【转】
- Linux Shortcuts and Commands:
- windows API 基本数据类型
- Ubuntu11.10源
- 【正则】匹配头尾,并且中间不能有特定字符串
- UVA 12452
- 监听input的动态
- C程序设计课程-2012电子信息 第三次上机实验
- android41_listView前言
- oracle 中 UPDATE nowait 的使用方法
- UISegmentedControl 分段控件-iOS开发
- 织梦DedeCMS编辑器fck更换成eWebEditor编辑器
- iPhone开发面试题--葵花宝典
- 用递归做螺旋矩阵 java版算法