zoukankan      html  css  js  c++  java
  • UVALive6900 Road Repair(树的点分治)

    题目大概说一棵树,树边有费用和收益两个属性,求一条收益和最大的路径满足费用和不超过C。

    树上任意两点的路径都可以看成是过某一个子树根的路径,显然树分治。

    治的时候要解决的一个问题是,找到费用小于等于某个数且收益最大的值。

    这个很容易想到用线段树,不过不想写线段树。。

    想了想,想到可以先排序,从小到大去找,之前找到哪现在就继续从那儿开始找,这样最多也就遍历一遍待查找数组,具体看代码。

    两次排序占大头,最后时间复杂度是O(nlog2n)。

    WA了一次,因为只考虑了两端都过根的路径,忽略了一端点是根的路径。。之前写树分治也是因为这个WA。。

      1 #include<cstdio>
      2 #include<cstring>
      3 #include<algorithm>
      4 using namespace std;
      5 #define INF (1<<30)
      6 #define MAXN 22222
      7 struct Edge{
      8     int v,b,c,next;
      9 }edge[MAXN<<1];
     10 int NE,head[MAXN];
     11 void addEdge(int u,int v,int b,int c){
     12     edge[NE].v=v; edge[NE].b=b; edge[NE].c=c; edge[NE].next=head[u];
     13     head[u]=NE++;
     14 }
     15 bool vis[MAXN];
     16 int size[MAXN];
     17 void getsize(int u,int fa){
     18     size[u]=1;
     19     for(int i=head[u]; i!=-1; i=edge[i].next){
     20         int v=edge[i].v;
     21         if(v==fa || vis[v]) continue;
     22         getsize(v,u);
     23         size[u]+=size[v];
     24     }
     25 }
     26 int mm,cen;
     27 void getcen(int u,int fa,int &tot){
     28     int res=tot-size[u];
     29     for(int i=head[u]; i!=-1; i=edge[i].next){
     30         int v=edge[i].v;
     31         if(v==fa || vis[v]) continue;
     32         getcen(v,u,tot);
     33         res=max(res,size[v]);
     34     }
     35     if(res<mm){
     36         mm=res;
     37         cen=u;
     38     }
     39 }
     40 int getcen(int u){
     41     getsize(u,u);
     42     mm=INF;
     43     getcen(u,u,size[u]);
     44     return cen;
     45 }
     46 struct Rec{
     47     int b,c;
     48     bool operator<(const Rec &r)const{
     49         return c<r.c;
     50     }
     51 }ra[MAXN],rb[MAXN];
     52 int tot,an,bn;
     53 void dfs(int u,int fa,int benfit,int cost){
     54     rb[bn].b=benfit;
     55     rb[bn].c=cost;
     56     bn++;
     57     for(int i=head[u]; i!=-1; i=edge[i].next){
     58         int v=edge[i].v;
     59         if(v==fa || vis[v]) continue;
     60         dfs(v,u,benfit+edge[i].b,cost+edge[i].c);
     61     }
     62 }
     63 int ans;
     64 void conqur(int u){
     65     an=1;
     66     ra[0].b=0; ra[0].c=0;
     67     for(int i=head[u]; i!=-1; i=edge[i].next){
     68         int v=edge[i].v;
     69         if(vis[v]) continue;
     70         bn=0;
     71         dfs(v,v,edge[i].b,edge[i].c);
     72         sort(ra,ra+an);
     73         sort(rb,rb+bn);
     74         int pa=an-1,pb=0;
     75         while(pb<bn){
     76             int mx=-1;
     77             for(int j=pa; j>=0; --j){
     78                 if(ra[j].c+rb[pb].c<=tot){
     79                     if(mx<ra[j].b+rb[pb].b){
     80                         mx=ra[j].b+rb[pb].b;
     81                         pa=j;
     82                     }
     83                 }
     84             }
     85             if(mx==-1) break;
     86             ans=max(ans,mx);
     87             ++pb;
     88         }
     89         for(int j=0; j<bn; ++j){
     90             ra[an++]=rb[j];
     91         }
     92     }
     93 }
     94 void divide(int u){
     95     u=getcen(u);
     96     vis[u]=1;
     97     conqur(u);
     98     for(int i=head[u]; i!=-1; i=edge[i].next){
     99         int v=edge[i].v;
    100         if(vis[v]) continue;
    101         divide(v);
    102     }
    103 }
    104 int main(){
    105     int t,n,a,b,c,d;
    106     scanf("%d",&t);
    107     while(t--){
    108         scanf("%d",&n);
    109         NE=0;
    110         memset(head,-1,sizeof(head));
    111         for(int i=1; i<n; ++i){
    112             scanf("%d%d%d%d",&a,&b,&c,&d);
    113             addEdge(a,b,d,c);
    114             addEdge(b,a,d,c);
    115         }
    116         scanf("%d",&tot);
    117         ans=0;
    118         memset(vis,0,sizeof(vis));
    119         divide(1);
    120         printf("%d
    ",ans);
    121     }
    122     return 0;
    123 }
  • 相关阅读:
    Eclipse配置Struts2
    Servlet读取头信息
    JAVA基础
    Start Tomcat v8.0 Server at localhost错误
    Eclipse 配置Server Location时灰色,不可用
    Windows 7安装apache-tomcat-8.0.24
    Sql developer——缺点
    Oracle Database,SQL Server,MySQL的比较
    poj1580---欧几里得算法(辗转相除法)
    poj1565---(数论)skew binary
  • 原文地址:https://www.cnblogs.com/WABoss/p/5443745.html
Copyright © 2011-2022 走看看