标签:style blog http color io os ar for sp
题意:带边权树上有白点和黑点,问你最多不经过k个黑点使得路径最长(注意,路径有负数)
解题思路:基于树的点分治。数的路径问题,具体看09QZC论文,特别注意 当根为黑时的情况
解题代码:
1 // File Name: spoj1825.cpp 2 // Author: darkdream 3 // Created Time: 2014年10月05日 星期日 20时20分33秒 4 5 #include<vector> 6 #include<list> 7 #include<map> 8 #include<set> 9 #include<deque> 10 #include<stack> 11 #include<bitset> 12 #include<algorithm> 13 #include<functional> 14 #include<numeric> 15 #include<utility> 16 #include<sstream> 17 #include<iostream> 18 #include<iomanip> 19 #include<cstdio> 20 #include<cmath> 21 #include<cstdlib> 22 #include<cstring> 23 #include<ctime> 24 #define LL long long 25 #define maxn 200005 26 using namespace std; 27 struct node{ 28 int ne; 29 int w; 30 node(int _ne,int _w) 31 { 32 ne = _ne ; 33 w = _w; 34 } 35 }; 36 int n ,K, m ; 37 int col[maxn]; 38 int vis[maxn]; 39 vector <node> mp[maxn]; 40 int sum[maxn]; 41 int mx[maxn]; 42 int cnum[maxn]; 43 void getsize(int k,int la) 44 { 45 sum[k] = 1; 46 mx[k] = 0; 47 if(col[k]) 48 { 49 cnum[k] = 1; 50 }else cnum[k] = 0; 51 int num = mp[k].size(); 52 int tt = 0 ; 53 for(int i = 0 ;i < num;i ++) 54 { 55 if(!vis[mp[k][i].ne] && mp[k][i].ne != la) 56 { 57 getsize(mp[k][i].ne,k); 58 mx[k] = max(sum[mp[k][i].ne],mx[k]); 59 sum[k] += sum[mp[k][i].ne]; 60 if(cnum[mp[k][i].ne] > tt) 61 tt = cnum[mp[k][i].ne]; 62 } 63 } 64 cnum[k] += tt; 65 66 } 67 int root; 68 int mxv; 69 int getroot(int k,int la ,int tans) 70 { 71 int tt = max(tans - sum[k],mx[k]); 72 if(tt < mxv) 73 { 74 mxv = tt; 75 root = k ; 76 } 77 int num = mp[k].size(); 78 for(int i = 0 ;i < num ;i ++) 79 { 80 if(!vis[mp[k][i].ne] && mp[k][i].ne != la) 81 { 82 getroot(mp[k][i].ne,k,tans); 83 } 84 } 85 } 86 LL ans = 0 ; 87 LL dp[maxn]; 88 LL tdp[maxn]; 89 bool cmp(node a, node b) 90 { 91 return cnum[a.ne] < cnum[b.ne]; 92 } 93 void getdep(int k ,int la,int tc,LL dep) 94 { 95 // printf("%d %d %d %lld\n",la,k,tc,dep); 96 int st = (col[k] == 1?1:0) ; 97 tdp[tc+st] = max(tdp[tc+st],dep); //这个点是G点的时候 98 int num = mp[k].size(); 99 for(int i = 0 ;i < num ;i ++) 100 { 101 if(!vis[mp[k][i].ne] && mp[k][i].ne != la ) 102 { 103 // printf("****%lld %d\n",dep,mp[k][i].w); 104 getdep(mp[k][i].ne,k,tc + st,dep + mp[k][i].w); 105 } 106 } 107 } 108 void solve(int k) 109 { 110 //printf("*****%d\n",k); 111 getsize(k,0); 112 mxv = 1e9; 113 getroot(k,0,sum[k]); 114 k = root; 115 int num = mp[k].size(); 116 memset(dp,0,(cnum[k]+3)*sizeof(LL)); 117 int tk ; 118 int st = 0 ; 119 if(col[k]) 120 { 121 tk = K + 1; 122 st = 1; 123 } 124 else tk = K ; 125 int la =0 ; 126 //int size = min(cnum[k],K); 127 sort(mp[k].begin(),mp[k].end(),cmp); 128 for(int i = 0 ;i < num ;i ++) 129 { 130 if(vis[mp[k][i].ne]) 131 continue; 132 memset(tdp,0,(cnum[mp[k][i].ne]+3)*sizeof(tdp[0])); 133 134 if(col[k]) 135 getdep(mp[k][i].ne,k,1,mp[k][i].w); 136 else 137 getdep(mp[k][i].ne,k,0,mp[k][i].w); 138 // printf("**********%d\n",tk); 139 140 141 int tt = min(cnum[mp[k][i].ne]+st,K); 142 for(int j = st ;j <= tt;j ++) 143 { 144 if(tk - j <= la) 145 { 146 if(tdp[j] + dp[tk-j]> ans) 147 { 148 ans = tdp[j] + dp[tk-j]; 149 } 150 }else{ 151 if(tdp[j] + dp[la]> ans) 152 { 153 ans = tdp[j] + dp[la]; 154 } 155 } 156 } 157 158 dp[0] = max(dp[0],tdp[0]); 159 //printf("%d %d\n",n,cnum[mp[k][i].ne]); 160 /*if(tdp[tt+st+1] != 0) 161 { 162 printf("&&&&&&&&&&&&&&\n"); 163 }*/ 164 for(int j = 1 ;j <= tt+st; j ++) 165 { 166 dp[j] = max(dp[j],tdp[j]); 167 dp[j] = max(dp[j],dp[j-1]); 168 } 169 la = tt + st; 170 } 171 //puts("**********8"); 172 vis[k] = 1; 173 for(int i = 0;i < num;i ++) 174 { 175 if(!vis[mp[k][i].ne]) 176 solve(mp[k][i].ne); 177 } 178 return; 179 } 180 int main(){ 181 // freopen("out","r",stdin); 182 scanf("%d %d %d",&n,&K,&m); 183 int temp ; 184 memset(vis,0,sizeof(vis)); 185 memset(col,0,sizeof(col)); 186 for(int i = 1;i <= n;i ++) 187 mp[i].clear(); 188 for(int i = 1;i <= m;i ++) 189 { 190 scanf("%d",&temp); 191 col[temp] = 1; 192 } 193 for(int i = 1;i <= n - 1;i ++) 194 { 195 int a, b , w; 196 scanf("%d %d %d",&a,&b,&w); 197 mp[a].push_back(node(b,w)); 198 mp[b].push_back(node(a,w)); 199 } 200 ans = 0; 201 solve(1); 202 printf("%lld\n",ans); 203 return 0; 204 }
标签:style blog http color io os ar for sp
原文地址:http://www.cnblogs.com/zyue/p/4013037.html