poj 3345 Bribing FIPA

4 篇文章 0 订阅
2 篇文章 0 订阅

比赛的时候做的这题,坑爹的,我这近段时间一直学树形dp,结果这唯一一道树形dp的题目我居然没看懂!!
这道题dp部分比较容易想出来,难点是输入格式,一直runtime error。
dp[v][j]:在结点v与它的子孙结点中选出j个城市需要付出的最小代价。

dp[v][j]=min(dp[v][j],dp[son][k]+dp[v][j-k]);//son为v的一个子结点

n和m的输入建议用sscanf,若s[0]==’#’,跳出循环,否则

sscanf(c,"%d%d",&n,&m);

我的输入部分用些乱,建议大家自己写。后面有测试代码。

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<map>
#include<string>
#include<vector>
using namespace std;
const int N=205;
const int INF=1<<30;
string s;
int dp[N][N],vis[N],sum[N],cost[N];
int n,m;
int tmp;
int minv;
char c[N];
vector<int> a[N];
map<string,int> cities;
void init()
{
    minv=INF;
    for(int i=0;i<=n;i++)
    {
        if(!a[i].empty())
            a[i].clear();
    }
    tmp=0;
    for(int i=0;i<=n;i++)
        for(int j=0;j<=n;j++)
        {
            if(j==0)
                dp[i][j]=0;
            else dp[i][j]=INF;
        }
        memset(vis,0,sizeof(vis));
        memset(sum,0,sizeof(sum));
}
void DP(int v)
{
    if(sum[v]==0)
    {
        dp[v][1]=cost[v];
        return ;
    }
    int t;
    for(int i=0;i<sum[v];i++)
    {
        int num=a[v][i];
        DP(num);
        t=0;
        for(int j=n;j>=0;j--)
        {
            for(int k=0;k<=n&&k<=j;k++)
            {
                if(dp[v][j-k]!=INF&&dp[num][k]!=INF)
                {
                    t=max(t,j);
                    dp[v][j]=min(dp[v][j],dp[num][k]+dp[v][j-k]);
                    if(v==0&&j>=m)
                        minv=min(minv,dp[v][j]);
                }
            }
        }
    }
    dp[v][t+1]=cost[v];
    return;
}
int main()
{
    //freopen("in.txt","r",stdin);
    while(gets(c))
    {
        if(!strcmp(c,"#"))
            break;
        sscanf(c,"%d%d",&n,&m);
        //cout<<n<<" "<<m<<endl;
        init();
        cities.clear();
        for(int i=1;i<=n;i++)
        {
            cin>>s;
            //cout<<s;
            int x=cities[s];
            if(!x)//对每一个city编号
            {
                cities[s]=++tmp;
                x=cities[s];
            }
            scanf("%d",&cost[x]);
            while(getchar()!='\n')
            {
                cin>>s;
                //cout<<" "<<s;
                int y=cities[s];
                if(!y)
                {
                    cities[s]=++tmp;
                    y=cities[s];
                }
                sum[x]++;
                a[x].push_back(y);
                vis[y]=1;
            }
            //cout<<endl;
        }
        for(int i=1;i<=n;i++)
        {
            if(!vis[i])
            {
                sum[0]++;
                a[0].push_back(i);
            }
        }
        DP(0);
        cout<<minv<<endl;
    }
    return 0;
}
输入(我只复制了前几个):
3 2
Aland 10
Boland 20 Aland
Coland 15
10 3
A 299 B C D E F G H I J
B 100
C 100
D 100
E 100
F 100
G 100
H 100
I 100
J 100
3 0
A 1
B 1
C 1
3 0
A 1
B 2
C 3
3 3
A 1
B 2
C 3
3 1
A 1
B 1
C 1
3 2
a 2 b c
b 1
c 1
3 2
a 3 b c
b 1
c 1
3 2
a 1 b c
b 1
c 1
100 91
ac 60 ar ft pl
ar 86 au ec sc
at 44 bg cm tq zb
au 54 aw by fg ka nl
aw 7 ir
bg 57 bz rt vn wg
by 34 hz ta yg
bz 30 ca ch
ca 40 ci ln md rr sq
ch 48 ed
ci 37 mc uu vu yf
cm 5 dp gl pw
dp 7 dr du ei mu nw
dr 4 fh fj
du 45 te
ec 77 eh ha
ed 67 on
eh 59 fv hx ow rm
ei 73 ip
fg 60 xt
fh 64
fj 62 ia po
ft 87 ig jb
fv 9 ho vx
gl 56 gp ij
gp 15 kb kf si yq
gz 69 ml
ha 95
ho 49 kd nh up vm
hx 80
hz 59
ia 63
ig 65
ij 9
ip 21 pb zg
ir 82 it
it 41
jb 38
ka 32 ne
kb 34 yn
kd 45 lx mz
kf 75 oj
ln 82
lx 64
mc 3
md 14 wy
ml 90
mu 4 zy
mz 99 wm
ne 67
nh 36 oh qj yw
nl 43 wv
nw 14
oh 42 pz
oj 78
on 16 sw ws
ow 64
pb 55 sd
pl 43
po 65 tu
pw 60
pz 22 sg
qj 99
rm 20
rr 66
rt 73
sc 27 ui xi
sd 11
sg 25
si 18
sq 83
sw 27
ta 32
te 71
tq 47
tu 81
ui 57
up 2
uu 10
vm 38
vn 27
vu 20
vx 73
wg 50 zx
wm 5 xm
ws 50
wv 84
wy 83
xi 1
xm 11
xt 68
yf 35
yg 21
yn 35
yq 36
yw 1
zb 44
zg 93
zx 91
zy 30
100 100
aa 24
ag 29 bb bv by ea
bb 6 ct eb hj ry
bo 75 dl dv ez go ih
bv 87 dc dp er hn
by 20 cg em
cg 37
ct 42 gw lk
dc 79 hx qs yu
dl 41 kh vn
dp 10 ed pq uq
dv 36 ej qx zz
ea 93 eu ro so
eb 54
ed 97 eh ho iz ja
eh 79 el nm tq
ej 99 ep hh on
el 20 gx jq
em 40 gj xz
ep 84 ge uh
er 10 fy hq ma nc zn
eu 39
ez 28
fy 32
ge 37 sv
gj 11 jm
go 65 jy rx
gw 82
gx 9 ui
hh 23 ii oh
hj 55
hn 28 ie lo sd
ho 28 nd px
hq 18
hx 85 if
ie 71 xu
if 92 qb zj
ih 48
ii 91 nv
iz 52 jo jp ke mv qk zr
ja 13 qp
jm 13
jo 13 rt
jp 69
jq 16
jy 47 ll
ke 97 yf
kh 42 zi
lk 3
ll 89 sa vg
lo 88
ma 76
mv 6
nc 77 nt
nd 96 xy
nm 67 zu
nt 68 pc
nv 43
oh 8 vs
on 73
pc 8
pq 44 sw tw
px 31
qb 70 rg
qk 92
qp 57
qs 58
qx 45 yr
rg 59
ro 77
rt 23
rx 60 tv
ry 97
sa 96
sd 64
so 9
sv 5 xx
sw 70
tq 16
tv 18
tw 57
uh 85
ui 20
uq 38
vg 97
vn 39
vs 62
xu 69
xx 58
xy 57
xz 23
yf 26
yr 49
yu 8
zi 5
zj 58
zn 30
zr 83
zu 31
zz 84
#
20
299
0
0
6
1
2
2
1
104
128
8
230
139
328
524287
135
20
45
75
80
165
525
201
75
499
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值