hdu 4313 Matrix 树形dp
2012-07-27 18:13
369 查看
dpn[x]表示以x为根的子树间互相不联通但是可能和x联通所需要删除的边权
dpy[x]表示以x为根的子树间互相不联通而且不能和x联通所需要删除的边权
遍历每个点,通过它的子节点信息更新它的信息,
当x的子节点y上有机器时: dpn[x]+=dpn[y]+cost;
设临时变量 temp>?=cost;
当子节点y上没有机器时:dpn[x]+=min(dpy[to]+cost,dpn[to]);
临时变量: temp>?=min(dpy[to]+cost,dpn[to])-dpy[to];
最后更新dpy[x];
if(x上没机器) dpy[x]=dpn[x]-temp;
复杂度O(n) 比较简单的中档题
dpy[x]表示以x为根的子树间互相不联通而且不能和x联通所需要删除的边权
遍历每个点,通过它的子节点信息更新它的信息,
当x的子节点y上有机器时: dpn[x]+=dpn[y]+cost;
设临时变量 temp>?=cost;
当子节点y上没有机器时:dpn[x]+=min(dpy[to]+cost,dpn[to]);
临时变量: temp>?=min(dpy[to]+cost,dpn[to])-dpy[to];
最后更新dpy[x];
if(x上没机器) dpy[x]=dpn[x]-temp;
复杂度O(n) 比较简单的中档题
#include<iostream> #include<vector> #include<algorithm> #include<cstdio> #include<queue> #include<stack> #include<string> #include<map> #include<set> #include<cmath> #include<cassert> #include<cstring> #include<iomanip> using namespace std; #ifdef _WIN32 typedef __int64 i64; #define out64 "%I64d\n" #define in64 "%I64d" #else typedef long long i64; #define out64 "%lld\n" #define in64 "%lld" #endif /************ for topcoder by zz1215 *******************/ #define FOR(i,a,b) for( int i = (a) ; i <= (b) ; i ++) #define FFF(i,a) for( int i = 0 ; i < (a) ; i ++) #define FFD(i,a,b) for( int i = (a) ; i >= (b) ; i --) #define S64(a) scanf(in64,&a) #define SS(a) scanf("%d",&a) #define LL(a) ((a)<<1) #define RR(a) (((a)<<1)+1) #define pb push_back #define CL(Q) while(!Q.empty())Q.pop() #define MM(name,what) memset(name,what,sizeof(name)) #define read freopen("in.txt","r",stdin) #define write freopen("out.txt","w",stdout) const int inf = 0x3f3f3f3f; const i64 inf64 = 0x3f3f3f3f3f3f3f3fLL; const double oo = 10e9; const double eps = 10e-9; const double pi = acos(-1.0); const int maxn = 100111; struct zz { int from; int to; int cost; }zx; int n,k; vector<zz>g[maxn]; bool you[maxn]; i64 dpn[maxn]; //和x不通 i64 dpy[maxn]; //和x通 int f[maxn]; void df1(int now) { int to; for(int i=0;i<g[now].size();i++) { to = g[now][i].to; if(f[to]==-1) { f[to]=now; df1(to); } } return ; } void df2(int now) { int to; int cost; i64 temp = 0; for(int i=0;i<g[now].size();i++) { to = g[now][i].to; cost = g[now][i].cost; if(to!=f[now]) { df2(to); if(you[to]) { dpn[now]+=dpn[to]+cost; if(cost>temp) { temp = cost; } } else { dpn[now]+=min(dpy[to]+cost,dpn[to]); if(min(dpy[to]+cost,dpn[to])-dpy[to]>temp) { temp = min(dpy[to]+cost,dpn[to])-dpy[to]; } } } } if(!you[now]) { dpy[now]=dpn[now]-temp; } return ; } i64 start() { for(int i=0;i<n;i++) { f[i]=-1; dpn[i]=0; dpy[i]=0; } f[0]=-2; df1(0); df2(0); if(!you[0]) { return dpy[0]; } else { return dpn[0]; } } int main() { int T; cin>>T; while(T--) { cin>>n>>k; for(int i=0;i<n;i++) { you[i]=false; g[i].clear(); } for(int i=1;i<=n-1;i++) { cin>>zx.from>>zx.to>>zx.cost; g[zx.from].pb(zx); swap(zx.from,zx.to); g[zx.from].pb(zx); } int now; for(int i=1;i<=k;i++) { cin>>now; you[now]=true; } cout<<start()<<endl; } return 0; }
相关文章推荐
- hdu 4313 Matrix(树形DP)
- hdu - 4313 - Matrix - 树形dp 或者 贪心
- HDU 4313 Matrix 树形dp
- HDU 4313 Matrix 树形dp
- hdu 4313 Matrix 树形dp
- HDU 4313 Matrix 贪心 || 树形dp
- HDU 4313 Matrix(树形dp)
- HDU 4313 Matrix 树状DP
- HDU 4313树形DP
- hdu4313 贪心并查集 || 树形dp
- hdu 2196 Computer (树形dp)
- hdu 1520 树形DP
- Hdu 6241 二分+树形dp
- BestCoder Round #65 HDU 5593 ZYB's Tree (树形DP)
- hdu 1011 Starship Troopers(树形DP+背包问题)
- hdu 3586 Information Disturbing (树形dp+二分)
- HDU 4126 Genghis Khan the Conqueror(最小生成树+树形DP)
- HDU 4313 Matrix(并查集/破坏边使得k个点两两不连通的最少代价)
- HDU 4081 Qin Shi Huang's National Road System prim + (DP 或 树形DP) 好题
- HDU 3639 Hawk-and-Chicken【强连通+树形DP】