Fzu 2157 ProgramCaicai's Trees【树型dp】
2017-06-09 15:46
295 查看
Problem 2157 ProgramCaicai's Trees
Accept: 62 Submit: 155
Time Limit: 15000 mSec Memory Limit : 32768 KB
Problem Description
Given a Tree of N nodes.Each node has exactly two labels.(0 and 1).
You must choose which label to assign to give the minimum cost.
The Cost is the sum of two parts:
1. For each node their is a cost assigned to the node for a given label.
2. For each pairs of Node connected their is a cost assigned to it according to it's labels.
Input
In the first line, there are a number T(<=50) denotes the number of test cases.In the second line, there are a number N(<=200000) denoting the number of Nodes.
In the third line, N numbers denoting the cost for each node assigned to label 0.
In the fourth line, N numbers denoting the cost for each node assigned to label 1.
In the next n-1 lines. each line containing six numbers P Q A B C D, P Q indicates there is a edge between P and Q , and A B C D are cost assigned to pairs of nodes which label is 00 01 10 11 accordingly.
The Tree root is always Node 1
Every cost is between 0 and 100
only 2 big cases
Output
The Minimum cost of the given tree.(A Integer)
Sample Input
14
3 1 1 3
4 0 0 4
1 2 0 1 1 0
2 3 0 1 1 0
2 4 0 1 1 0
Sample Output
8题目大意:
一共有N个点,每个点只能标号为0或者1 ,已知一个点被标号0或者1的价值,以及两个点之间两点设定的标号的边的权值,问设定完,整个图所有权值加和最小是多少。
思路:
一道树Dp.
设定dp【i】【2】表示节点i标号为0或者1的最小花费。
那么我们从节点1开始Dfs并且维护Dp值即可。
不难推出其状态转移方程:
dp【i】【0】+=min(dp【v】【0】+a【0】【0】+dp【v】【1】+a【0】【1】);
dp【i】【1】+=min(dp【v】【0】+a【1】【0】+dp【v】【1】+a【1】【1】);
Ac代码:
#include<iostream>
#include<stdio.h>
#include<string.h>
using namespace std;
struct node
{
int from;
int to;
int w1;
int w2;
int w3;
int w4;
int next;
}e[200050*2];
int head[200050];
int a[200050];
int b[200050];
int dp[200050][2];
int cont;
void add(int from,int to,int a,int b,int c,int d)
{
e[cont].to=to;
e[cont].w1=a;
e[cont].w2=b;
e[cont].w3=c;
e[cont].w4=d;
e[cont].next=head[from];
head[from]=cont++;
}
int Dp(int u,int from)
{
dp[u][0]=a[u];
dp[u][1]=b[u];
for(int i=head[u];i!=-1;i=e[i].next)
{
int v=e[i].to;
int w1=e[i].w1;
int w2=e[i].w2;
int w3=e[i].w3;
int w4=e[i].w4;
if(v==from)continue;
Dp(v,u);
dp[u][0]+=min(dp[v][0]+w1,dp[v][1]+w2);
dp[u][1]+=min(dp[v][0]+w3,dp[v][1]+w4);
}
}
int main()
{
int t;
scanf("%d",&t);
while(t--)
{
int n;
cont=0;
memset(dp,0,sizeof(dp));
memset(head,-1,sizeof(head));
scanf("%d",&n);
for(int i=1;i<=n;i++)scanf("%d",&a[i]);
for(int i=1;i<=n;i++)scanf("%d",&b[i]);
for(int i=1;i<=n-1;i++)
{
int x,y,w1,w2,w3,w4;
scanf("%d%d%d%d%d%d",&x,&y,&w1,&w2,&w3,&w4);
add(x,y,w1,w2,w3,w4);
add(y,x,w1,w3,w2,w4);
}
Dp(1,-1);
// printf("%d %d\n",dp[1][0],dp[1][1]);
printf("%d\n",min(dp[1][1],dp[1][0]));
}
}
dp【i】【0】+=min(dp【v】【0】+a【0】【0】+dp【v】【1】+a【0】【1】);
相关文章推荐
- FZU -- 2157 ProgramCaicai's Trees
- fzu2157(树形)
- hdu 1392 fzu 1333 Surround the Trees 简单凸包
- FZU 1775 Counting Binary Trees 卡特兰数前n项和%m(m可为非素数
- FZU 1775 Counting Binary Trees(卡特兰数前n项和模m)
- FZU 2157 树形DP
- FZU 2157 树形DP
- fzu2157(树形dp)
- fzu 1775 Counting Binary Trees 卡特兰数取模求和
- FZU 1876 JinYueTuan(排列组合)
- FZU 2109 奇偶
- js.program code
- [C How To Program] 习题6.35 二分查找
- Write a program that gives count of common characters presented in an array of strings..(or array of
- Program Day by Day
- UVa 122 - Trees on the level
- Common Tangents FZU - 2213
- How Run Class library program (SlickUpload)
- initerrlog: 无法打开错误日志文件 'D:\Program Files\Microsoft SQL Server\MSSQL10_50.MSSQLSERVER\MSSQL\Log 解决办法
- HDU1693 Eat the Trees(插头dp)