题意:
边权可能为负
思路:
感觉我自己写的还是太过僵硬了,可以灵活一点,比如可以多写几个不同的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