• 博客园logo
  • 会员
  • 周边
  • 众包
  • 新闻
  • 博问
  • 闪存
  • 赞助商
  • Chat2DB
    • 搜索
      所有博客
    • 搜索
      当前博客
  • 写随笔 我的博客 短消息 简洁模式
    用户头像
    我的博客 我的园子 账号设置 会员中心 简洁模式 ... 退出登录
    注册 登录
AC_Artist.zig_zag
然而我依然在补题、
博客园    首页    新随笔    联系   管理    订阅  订阅

Spoj 1825 Freetour2

点分治第二题,分治过程写的比较熟练了,但搞答案的时候还是想了好久,写了好久.......
主要解释一下求g的那块吧:
首先dep[i]表示rot的第i个儿子的子树里黑点最多的路径的的黑点数。

黑点限制是K,我们可以求出rot的每一个儿子i黑点数为j的最大长度g[i,j],然后每次求出一个j1+j2<=K,且g[i1,j1]+g[i2,j2]最大的。

如果我们枚举i2,那么只需要求出一个可以和i2配并且最长的i1就行了。这个可以用个什么数据结构维护,也可以“暴力”。由于顺序是对答案没有影响的,那么我们按照dep升序排序,然后按照这个顺序计算,mg[j]表示前i个点的g[j]的最大值,如果维护好mg,就可以用g+mg来更新答案了。最恶心就是更新答案这里,假设当前枚举到了g[j],我们需要找到一个≤K-j-black[rot]的,但是我们不能直接用mg[K-j-black[rot]],因为前面i-1个点可能没有达到K-j-black[rot]个黑点的,这样我们得用第i-1个点的dep。就说这些吧,其他地方看论文就行了。

Freetour
  1 #include<iostream>
  2 #include<cstdio>
  3 #include<algorithm>
  4 #include<cmath>
  5 #include<cstring>
  6 #define inf 2147483647
  7 #define maxn 420000
  8 using namespace std;
  9 
 10 struct et
 11 {
 12     int s,t,val,next;
 13 }e[maxn];
 14 int fa[maxn],fir[maxn],size[maxn];
 15 int dep[maxn],son[maxn],g[maxn],mg[maxn],way[maxn];
 16 bool ex[maxn],black[maxn];
 17 int n,m,p,tot,ans,num;
 18 
 19 void dfs(int now)
 20 {
 21     size[now]=1;
 22     for (int j=fir[now];j;j=e[j].next)
 23     {
 24         int k=e[j].t;
 25         if (k!=fa[now])
 26         {
 27             fa[k]=now;
 28             dfs(k);
 29             size[now]+=size[k];
 30         }
 31     }
 32 }
 33 
 34 void choose(int &rot)
 35 {
 36     int now,mx=0;
 37     for (int j=fir[rot];j;j=e[j].next)
 38     {
 39         int k=e[j].t;
 40         if (ex[k]&&k!=fa[rot]&&size[k]>mx)
 41         {
 42             mx=size[k];
 43             now=k;
 44         }
 45     }
 46     if (mx>num/2) 
 47     {
 48         size[rot]-=size[now];
 49         size[now]=num;
 50         fa[rot]=now;
 51         fa[now]=0;
 52         choose(rot=now);
 53     }
 54 }
 55 
 56 int getdep(int now)
 57 {
 58     int tmp=0;
 59     for (int j=fir[now];j;j=e[j].next)
 60     {
 61         int k=e[j].t;
 62         if (ex[k]&&k!=fa[now]) tmp=max(tmp,getdep(k));
 63     }
 64     return black[now]+tmp;
 65 }
 66 
 67 int getway(int now,int sum,int dis)
 68 {
 69     g[sum]=max(g[sum],dis);
 70     for (int j=fir[now];j;j=e[j].next)
 71     {
 72         int k=e[j].t;
 73         if (ex[k]&&k!=fa[now]) getway(k,sum+black[k],dis+e[j].val);
 74     }
 75 }
 76 
 77 bool cmp(int a,int b)
 78 {
 79      return dep[e[a].t]<dep[e[b].t];
 80 }
 81 
 82 void solve(int rot)
 83 {
 84     if (num==1) return;
 85     choose(rot);
 86     int sum=0;
 87     for (int j=fir[rot];j;j=e[j].next)
 88     {
 89         int k=e[j].t;
 90         if (ex[k]) sum++,dep[k]=getdep(k),way[sum]=j; 
 91     }
 92     sort(way+1,way+sum+1,cmp);
 93     for (int i=0;i<=dep[e[way[sum]].t];i++) mg[i]=-inf;
 94     for (int i=1;i<=sum;i++)
 95     {
 96         int k=e[way[i]].t;
 97         for (int j=0;j<=dep[k];j++) g[j]=-inf;
 98         getway(k,black[k],e[way[i]].val);
 99         if (i!=1)
100         {
101            for (int j=0;j<=p-black[rot]&&j<=dep[k];j++)
102            {
103                int len=min(p-black[rot]-j,dep[e[way[i-1]].t]);
104                if (mg[len]==-inf) break;
105                if (g[j]!=-inf) ans=max(ans,mg[len]+g[j]);
106            }    
107         }
108         for (int j=0;j<=dep[k];j++)
109         {
110             mg[j]=max(g[j],mg[j]);
111             if (j) mg[j]=max(mg[j-1],mg[j]);
112             if (j+black[rot]<=p) ans=max(ans,mg[j]);
113         }   
114     }
115     ex[rot]=0;
116     for (int j=fir[rot];j;j=e[j].next)
117     {
118         int k=e[j].t;
119         if (ex[k]) 
120         {
121             num=size[k];
122             solve(k);
123         }
124     }
125 }
126 
127 void add(int x,int y,int z)
128 {
129     e[++tot].s=x; e[tot].t=y; e[tot].val=z; e[tot].next=fir[x]; fir[x]=tot;
130     e[++tot].s=y; e[tot].t=x; e[tot].val=z; e[tot].next=fir[y]; fir[y]=tot;
131 }
132 
133 int main()
134 {
135     //freopen("freetour.in","r",stdin);
136     scanf("%d %d %d",&n,&p,&m);
137     int x,y,z;
138     tot=0;
139     for (int i=1;i<=m;i++)
140     {
141         scanf("%d",&x);
142         black[x]=1;
143     }
144     for (int i=1;i<n;i++)
145     {
146         scanf("%d %d %d",&x,&y,&z);
147         add(x,y,z);
148     }
149     memset(ex,1,sizeof(ex));
150     dfs(1);
151     num=n;ans=0;
152     solve(1);
153     printf("%d\n",ans);
154 }

 

AC without art, no better than WA !
posted @ 2013-04-02 10:18  Zig_zag  阅读(190)  评论(0)    收藏  举报
刷新页面返回顶部
博客园  ©  2004-2025
浙公网安备 33010602011771号 浙ICP备2021040463号-3