【SPOJ1825】Free tour II (点分治,启发式)

题意:

边权可能为负

思路:

感觉我自己写的还是太过僵硬了,可以灵活一点,比如可以多写几个不同的dfs求出不同的信息,而不是压到同一个dfs里

  1 #include<cstdio>
  2 #include<cstring>
  3 #include<string>
  4 #include<cmath>
  5 #include<iostream>
  6 #include<algorithm>
  7 #include<map>
  8 #include<set>
  9 #include<queue>
 10 #include<vector>
 11 using namespace std;
 12 typedef long long ll;
 13 typedef unsigned int uint;
 14 typedef unsigned long long ull;
 15 typedef pair<int,int> PII;
 16 typedef vector<int> VI;
 17 #define fi first
 18 #define se second s
 19 #define MP make_pair
 20 #define N   410000
 21 #define M   1100000
 22 #define MOD 1000000007
 23 #define eps 1e-8 
 24 #define pi acos(-1)
 25 #define oo 2e9+1
 26 
 27 struct node
 28 {
 29     int x,id;
 30 }b[N];
 31  
 32 
 33 int head[N],vet[N],nxt[N],len[N],dis[N],dep[N],mxdep[N],son[N],flag[N],c[N],a[N],f[N],tmp[N],mx[N],
 34     n,K,tot,top,ans,sum,root; 
 35     
 36 
 37 
 38 
 39 int read()
 40 { 
 41    int v=0,f=1;
 42    char c=getchar();
 43    while(c<48||57<c) {if(c=='-') f=-1; c=getchar();}
 44    while(48<=c&&c<=57) v=(v<<3)+v+v+c-48,c=getchar();
 45    return v*f;
 46 }
 47 
 48 bool cmp(node a,node b)
 49 {
 50     return a.x<b.x||
 51            (a.x==b.x&&a.id<b.id);
 52 
 53 }
 54 
 55 
 56 
 57 void add(int a,int b,int c)
 58 {
 59     nxt[++tot]=head[a];
 60     vet[tot]=b;
 61     len[tot]=c;
 62     head[a]=tot;
 63 }
 64 
 65 void getroot(int u,int fa)
 66 {
 67     son[u]=1; c[u]=0;
 68     int e=head[u];
 69     while(e)
 70     {
 71         int v=vet[e];
 72         if(v!=fa&&!flag[v])
 73         {
 74             getroot(v,u);
 75             son[u]+=son[v];
 76             c[u]=max(c[u],son[v]);
 77         }
 78         e=nxt[e];
 79     }
 80     c[u]=max(c[u],sum-c[u]);
 81     if(c[u]<c[root]) root=u;
 82 }
 83 
 84 void dfs(int u,int fa)
 85 {
 86     mxdep[u]=dep[u];
 87     int e=head[u];
 88     while(e)
 89     {
 90         int v=vet[e];
 91         if(v!=fa&&!flag[v])
 92         {
 93             dep[v]=dep[u]+a[v];
 94             dis[v]=dis[u]+len[e];
 95             dfs(v,u);
 96             mxdep[u]=max(mxdep[u],mxdep[v]);
 97         }
 98         e=nxt[e];
 99     }
100 }
101 
102 void getmx(int u,int fa)
103 {
104     tmp[dep[u]]=max(tmp[dep[u]],dis[u]);
105     int e=head[u];
106     while(e)
107     {
108         int v=vet[e];
109         if(v!=fa&&!flag[v]) getmx(v,u);
110         e=nxt[e];
111     }
112 }
113 
114 void work(int u)
115 {
116     flag[u]=1; 
117     f[0]=0; 
118     if(a[u]) K--;
119     int m=0;
120     int e=head[u];
121     while(e)
122     {
123         int v=vet[e];
124         if(!flag[v])
125         {
126             top=0;
127             dep[v]=a[v];
128             dis[v]=len[e];
129             dfs(v,u);
130             b[++m].x=mxdep[v];
131             b[m].id=v;
132         }
133         e=nxt[e];
134     }
135     
136 
137     sort(b+1,b+m+1,cmp);
138     for(int i=1;i<=m;i++)
139     {
140         int v=b[i].id;
141         getmx(v,u);
142         int now=0;
143         if(i>1)
144         {
145             for(int j=b[i].x;j>=0;j--)
146             {
147                 while(now+j<K&&now<b[i-1].x)
148                 {
149                     now++;
150                     mx[now]=max(mx[now],mx[now-1]);
151                 }
152                 if(now+j<=K) ans=max(ans,mx[now]+tmp[j]); 
153             }
154         }
155         if(i<m)
156         {
157             for(int j=0;j<=b[i].x;j++)
158             {
159                 mx[j]=max(mx[j],tmp[j]);
160                 tmp[j]=0;
161             }
162         }
163          else
164          {
165               for(int j=0;j<=b[i].x;j++)
166               {
167                   if(j<=K) ans=max(ans,max(tmp[j],mx[j]));
168                   tmp[j]=mx[j]=0;
169              }
170          }
171     }
172             
173             
174         
175     if(a[u]) K++;
176     e=head[u];
177     while(e)
178     {
179         int v=vet[e];
180         if(!flag[v])
181         {
182             sum=son[v]; root=0;
183             getroot(v,u);
184             work(root);
185         }
186         e=nxt[e];
187     }
188 
189     
190 }
191 
192 int main()
193 {
194     freopen("spoj1825.in","r",stdin);
195     freopen("spoj1825.out","w",stdout);
196     int m;
197     scanf("%d%d%d",&n,&K,&m);
198     for(int i=1;i<=m;i++)
199     {
200         int x;
201         scanf("%d",&x);
202         a[x]=1;
203     }
204     for(int i=1;i<=n-1;i++)
205     {
206         int x,y,z;
207         scanf("%d%d%d",&x,&y,&z);
208         add(x,y,z);
209         add(y,x,z);
210     }
211     ans=0;
212     root=0; sum=n; c[0]=n;
213 
214     getroot(1,0);
215     work(root); 
216     printf("%d
",ans);
217     return 0;
218 }
219     
220     
221 
222 
223             
224         
原文地址:https://www.cnblogs.com/myx12345/p/9716504.html