首页 新闻 会员 周边

一个小的算法问题。

0
悬赏园豆:30 [已解决问题] 解决于 2014-09-21 10:40

五一来临,某地下超市为了便于疏通和指挥密集的人员和车辆,以免造成超市内的混乱和拥挤,准备临时从外单位调用部分保安来维持交通秩序。
已知整个地下超市的所有通道呈一棵树的形状;某些通道之间可以互相望见。总经理要求所有通道的每个端点(树的顶点)都要有人全天候看守,在不同的通道端点安排保安所需的费用不同。
一个保安一旦站在某个通道的其中一个端点,那么他除了能看守住他所站的那个端点,也能看到这个通道的另一个端点,所以一个保安可能同时能看守住多个端点(树的结点),因此没有必要在每个通道的端点都安排保安。
请你帮助超市经理策划安排,在能看守全部通道端点的前提下,使得花费的经费最少。

Input

第1行 n,表示树中结点的数目。
第2行至第n+1行,每行描述每个通道端点的信息,依次为:该结点标号i(0<i<=n),在该结点安置保安所需的经费k(<=10000),该边的儿子数m,接下来m个数,分别是这个节点的m个儿子的标号r1,r2,...,rm。
对于一个n(0 < n <= 1500)个结点的树,结点标号在1到n之间,且标号不重复。

Output

最少的经费。

Sample Input

6
1 30 3 2 3 4
2 16 2 5 6
3 5 0
4 4 0
5 11 0
6 5 0

Sample Output

25


下面是我的代码,不知道为何WA 已经n++次了QAQ。。。就是找不出错误在哪里,。。第一次做树形dp,受打击呀。。。。希望各路前辈或者知道的人帮帮忙。到了这个地步感觉调试只能是浪费时间。。

#include<cstdio>
#include<vector>
#include<cstring>
using namespace std;
const int MAXN = 1510;
int n;
int f[MAXN][2];
int vis[MAXN][MAXN];
int v0[MAXN];
int w[10010],a[10010],temp=0;
void dfs(int u){
  v0[u] = true;
  for(int i=1; i<=n;i++)

  {
    if(!vis[u][i])

      {continue;}
    if(v0[i])

      {continue;}
    dfs(i);
    f[u][0]+=f[i][1];
    f[u][1]+=min(f[i][1],f[i][0]);
  }
}
int main(){
  scanf("%d", &n);
  int x,v,u;
  memset(vis, 0, sizeof(vis));
  memset(v0,0,sizeof(v));
  for(int i=1; i<=n; i++){
  scanf("%d%d%d", &a[i],&w[i],&x);
  while(x--){
  scanf("%d", &v);
  vis[a[i]][v]=1;vis[v][a[i]]=1;
  }
}
  for(int i=0; i<=n; i++)
    {f[i][1] = w[i]; f[i][0] = 0; }
  if(n==1)

    {printf("%d\n",w[n]);return 0;}
  else dfs(1);
  printf("%d\n", min(f[1][0], f[1][1]));
  return 0;
}

尽善尽美#的主页 尽善尽美# | 初学一级 | 园豆:152
提问于:2014-09-19 21:53
< >
分享
最佳答案
1

有点复杂。

收获园豆:30
519740105 | 大侠五级 |园豆:5810 | 2014-09-20 12:48

http://xcacm.hfut.edu.cn/oj/problem.php?id=1046

可以帮忙看看吗?告诉我哪里错了,还是思路就是不对的就好

尽善尽美# | 园豆:152 (初学一级) | 2014-09-20 17:59

@尽善尽美#: 

我运行你的代码,结果是25,有什么问题吗?

519740105 | 园豆:5810 (大侠五级) | 2014-09-20 19:31

@519740105: 那个,我自己想的数据测试也是正确的。。但是提交就wa了。所以不明白现在

尽善尽美# | 园豆:152 (初学一级) | 2014-09-20 20:26

@尽善尽美#: 不明白你的意思,你的代码我也没细看,只是把代码弄到系统后,是能得到25的。

根据图,25的结果有两个方案:全叶子(4人)和234,其实也有最优的选择需求,具体怎么样就看你了。

我没对你的代码研究,vis怎么用的也不明白,只是模拟你的输入初始化数组的,下面是我的实验代码:

#include "stdafx.h"
#include "MGPath.h"
#include<cstdio>
#include<vector>
#include<cstring>

using namespace std;

const int MAXN = 1510;

int n;
int f[MAXN][2];
int vis[MAXN][MAXN];
int v0[MAXN];
int w[10010],a[10010],temp=0;

void dfs(int u){
    v0[u] = true;
    for(int i=1; i<=n;i++)
    {
        if(!vis[u][i])
        {continue;}
        if(v0[i])

        {continue;}
        dfs(i);
        f[u][0]+=f[i][1];
        f[u][1]+=min(f[i][1],f[i][0]);
    }
}
void init()
{
    n = 6;
    a[1] = 1;
    w[1] = 30;
    vis[a[1]][2] = 1;
    vis[2][a[1]] = 1;
    vis[a[1]][3] = 1;
    vis[3][a[1]] = 1;
    vis[a[1]][4] = 1;
    vis[4][a[0]] = 1;
    a[2] = 2;
    w[2] =16;
    vis[a[2]][5] = 1;
    vis[5][a[2]] = 1;
    vis[a[2]][6] = 1;
    vis[6][a[2]] = 1;
    a[3] = 3;
    w[3] = 5;
    a[4] = 4;
    w[4] = 4;
    a[5] = 5;
    w[5] = 11;
    a[6] = 6;
    w[6] = 5;
}
void run(){
    init();
    //scanf("%d", &n);
    //int x,v,u;
    //memset(vis, 0, sizeof(vis));
    //memset(v0,0,sizeof(v));
    //for(int i=1; i<=n; i++){
    //    scanf("%d%d%d", &a[i],&w[i],&x);
    //    while(x--){
    //        scanf("%d", &v);
    //        vis[a[i]][v]=1;vis[v][a[i]]=1;
    //    }
    //}
    for(int i=0; i<=n; i++)
    {f[i][1] = w[i]; f[i][0] = 0; }
    if(n==1)

    {printf("%d\n",w[n]);return;}
    else dfs(1);
    printf("%d\n", min(f[1][0], f[1][1]));
}
519740105 | 园豆:5810 (大侠五级) | 2014-09-20 21:52

@519740105: vis就是邻接矩阵用来存树的,标记为1的就是两个节点间相连。25的最优方案确实是2 3 4点,这个是肯定的。这个就是部分数据正确不能代表所有的数据都对,只是我现在还没能发现错误的那些数据,所以不知从何下手去改了QAQ,谢谢你耐心的回答

尽善尽美# | 园豆:152 (初学一级) | 2014-09-21 00:06

@尽善尽美#: 3456的结果也是25

519740105 | 园豆:5810 (大侠五级) | 2014-09-21 08:26

@519740105: 恐怕你没理解题目意思,3456 并没有覆盖所有的边

尽善尽美# | 园豆:152 (初学一级) | 2014-09-21 09:10

@尽善尽美#: 对。我只简单的看所有节点了。

519740105 | 园豆:5810 (大侠五级) | 2014-09-21 09:38

@519740105: 完了 我自己弄吧,多谢你

尽善尽美# | 园豆:152 (初学一级) | 2014-09-21 10:39
其他回答(1)
1

给个链接啊

莫扎特的代码 | 园豆:204 (菜鸟二级) | 2014-09-20 10:34

http://xcacm.hfut.edu.cn/oj/problem.php?id=1046

谢谢你了,

支持(0) 反对(0) 尽善尽美# | 园豆:152 (初学一级) | 2014-09-20 17:58
清除回答草稿
   您需要登录以后才能回答,未注册用户请先注册