这道题的输入太特么的诡异了,我已经伤了,看得别人的输入,而且一开始的时候我把有大于M个孩纸的点当成M个来算,又是WA了半天。。。现在想想这样是错的,
原因:如果只有从 i 到 i +k (i+k〉M)而且i+k要小于能到M的 ,那么这个时候求出的就不是最小值。。。。。。。。。
不过这题最坑的就是输入了。。。本来是道简单的树形DP的。。。。。已经伤了。。。
AC代码如下:
#include <cstdio>
#include <cstring>
#include <string>
#include <algorithm>
#include <iostream>
#include <map>
#include <sstream>
using namespace std;
#define MAX 0x3f3f3f3f
typedef struct{
int to, next;
}Edge;
int N, M, cost[201];
int dp[201][201];
int parent[201], child[201];
bool mark[201];
map<string,int> name_num;
map<int,string> num_name;
int head[201], tot;
Edge edge[500];
void add_edge( int a, int b ){
edge[tot].to = b;
edge[tot].next = head[a];
head[a] = tot++;
}
void initial(){
char str[210];
stringstream s;
string con;
tot = 0;
memset( head, -1, sizeof( head ) );
memset( parent, -1, sizeof( parent ) );
memset( child, 0, sizeof( child ) );
memset( dp, -1, sizeof( dp ) );
memset( mark, false, sizeof( mark ) );
name_num.clear();
num_name.clear();
int temp = 1;
for( int i = 1; i <= N; i++ ){
gets(str);
s.clear();
s.str( str );
s >> con;
int names_id_now = name_num[con];
if( !names_id_now ){
name_num[con] = temp++;
}
names_id_now = name_num[con];
s >> cost[names_id_now];
while( s >> con ){
if( !name_num[con] ){
name_num[con] = temp++;
}
add_edge( names_id_now, name_num[con] );
parent[name_num[con]] = names_id_now;
}
}
}
void DFS( int pos ){
dp[pos][0] = 0;
for( int i = head[pos]; i != -1; i = edge[i].next ){
int to = edge[i].to;
DFS( to );
child[pos] += child[to];//这里不能单纯的++。。。。
for( int j = N; j >= 0; j-- ){
for( int k = j; k >= 0; k-- ){
if( dp[to][k] != -1 && dp[pos][j-k] != -1 ){
if( dp[pos][j] == -1 ){
dp[pos][j] = dp[pos][j-k] + dp[to][k];
}else{
dp[pos][j] = min( dp[pos][j], dp[pos][j-k] + dp[to][k] );
}
}
}
}
}
child[pos]++;
int temp = child[pos];
dp[pos][temp] = dp[pos][temp] == -1 ? cost[pos] : min( dp[pos][temp], cost[pos] );
}
int main(){
char str[222];
while( gets(str) ){
if(str[0]=='#')
break;
sscanf(str,"%d%d",&N,&M);
initial();
for( int i = 1; i <= N; i++ ){
if( parent[i] == -1 ){
DFS( i );
}
}
int temp_dp[202];
memset( temp_dp, -1, sizeof( temp_dp ) );
temp_dp[0] = 0;
for( int i = 1; i <= N; i++ ){
if( parent[i] == -1 ){
for( int j = N; j >= 0; j-- ){
for( int k = j; k >= 0; k-- ){
if( dp[i][k] != -1 && temp_dp[j-k] != -1 ){
if( temp_dp[j] == -1 ){
temp_dp[j] = temp_dp[j-k] + dp[i][k];
}else{
temp_dp[j] = min( temp_dp[j], temp_dp[j-k] + dp[i][k] );
}
}
}
}
}
}
int ans = MAX;
for( int i = M; i <= N; i++ ){
if( temp_dp[i] != -1 ){
ans = min( temp_dp[i], ans );
}
}
cout << ans << endl;
}
return 0;
}