您的位置:首页 > 大数据 > 人工智能

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

1

4

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