HDU 3586 Information Disturbing (枚举+树形DP)
来源:互联网 发布:crossover mac破解 编辑:程序博客网 时间:2024/06/15 11:20
题意:给定一个带权无向树,要切断所有叶子节点和1号节点(总根)的联系,每次切断边的费用不能超过上限limit,问在保证总费用<=m下的最小的limit。
按这题的要求:
要使得limit尽可能的小,但是又要满足<=m;这两个是矛盾的,比如:假设切断两个5或切断一个6都可以试树和“1”节点失去联系。因为要使limit小,切断两根用费为5的 比切断一根 花费为6更佳,但是这样总费用却多了4,可能就使得总费用超m了。
所以想在一次dfs里把limit和总费用都解决,几乎是不可能的……所以这题看似是简单,结果想了很久却不会做……
正解是二分枚举limit,初始l=1,r=最大边权;判断在该limit下能否符合m。能则缩小limit,否则增大limit。复杂度是 O(nlogm)完全是可以接受的。
然而我偷了一下懒直接一个for循环拍过去正好卡这个时间过去了(数据强肯定跪)
【代码】
/* ***********************************************Author :angon************************************************ */#include <stdio.h>#include <string.h>#include <iostream>#include <algorithm>#include <stack>#include <vector>#include <queue>#include <set>#include <map>#include <string>#include <math.h>#include <stdlib.h>#include <time.h>using namespace std;#define showtime fprintf(stderr,"time = %.15f\n",clock() / (double)CLOCKS_PER_SEC)#define lld %I64d#define REP(i,k,n) for(int i=k;i<n;i++)#define REPP(i,k,n) for(int i=k;i<=n;i++)#define scan(d) scanf("%d",&d)#define scanl(d) scanf("%I64d",&d)#define scann(n,m) scanf("%d%d",&n,&m)#define scannl(n,m) scanf("%I64d%I64d",&n,&m)#define mst(a,k) memset(a,k,sizeof(a))#define LL long long#define N 1005#define mod 1000000007inline int read(){int s=0;char ch=getchar();for(; ch<'0'||ch>'9'; ch=getchar());for(; ch>='0'&&ch<='9'; ch=getchar())s=s*10+ch-'0';return s;}struct Edge{ int v,w,next;}edge[N*2];int head[N],tot;void addedge(int u,int v,int w){ edge[tot] = (Edge) {v,w,head[u]}; head[u] = tot++;}int n,m;int dp[N]; //总花费void dfs(int u,int fa,int M){ int flag=0; dp[u]=0; for(int i=head[u]; ~i; i=edge[i].next) { int v = edge[i].v; int w = edge[i].w; if(v==fa) continue; flag=1; dfs(v,u,M); if(w > M) //不能切断这条边,那只能靠儿子 dp[u] += dp[v]; else //能切,则选择小的那个 dp[u] += min(dp[v],w); } if(flag==0) dp[u] = 100001;}int main(){ //freopen("in.txt","r",stdin); //freopen("out.txt","w",stdout); while(~scann(n,m) && (m||n)) { mst(head,-1); tot=0; int maxc=0; REP(i,1,n) { int u,v,w; scann(u,v);scan(w); addedge(u,v,w); addedge(v,u,w); maxc=max(w,maxc); } int flag=0; for(int i=1;i<=maxc;i++) { dfs(1,-1,i); if(dp[1]<=m) { printf("%d\n",i); flag=1; break; } } if(!flag) printf("-1\n"); } return 0;}
0 0
- HDU 3586 Information Disturbing (枚举+树形DP)
- HDU 3586 Information Disturbing 树形DP
- (简单) 树形dp HDU 3586 Information Disturbing
- hdu 3586 Information Disturbing 树形dp+二分
- HDU 3586 Information Disturbing(树形DP)
- hdu 3586 Information Disturbing(树形dp)
- HDU 3586 Information Disturbing 二分+树形DP
- HDU 3586 Information Disturbing (树形DP+二分)
- hdu 3586 Information Disturbing 删边类树形DP
- HDU 3586 Information Disturbing(树形DP)
- hdu 3586 Information Disturbing(树形dp)
- HDU 3586 Information Disturbing 树形DP+二分
- hdu 3586 Information Disturbing 树形dp+二分
- hdu 3586 Information Disturbing(树形dp)
- HDU 3586 Information Disturbing(树形DP + 二分)
- 【HDU】3586 Information Disturbing 二分+树形dp
- hdu 3586 Information Disturbing(树形dp + 二分)
- hdu 3586 Information Disturbing(树形DP+二分查找+删变暖)
- 判断NSString字符串或NSArray数组是否为空
- JS 图片幻灯片
- Java中equals和==的区别
- Spring 事务配置
- jquery中ajax处理跨域的三大方式
- HDU 3586 Information Disturbing (枚举+树形DP)
- c++数据类型各占多少字节
- POJ1830 开关问题
- WiFi简介
- lvs、haproxy、nginx 负载均衡的比较分析
- JavaScript encode
- HashMap源码阅读
- Activity中onNewIntent的使用
- bzoj1085