POJ 1770 Special Experiment

Special Experiment

題目描述同POJ1192一樣繁瑣。。。意思很簡單,如果兩個原子的能量之差剛好是某個光子的能量,那麼將會引起爆炸。。現在選取若干個原子,使得他們的能量之和最大,且不發生爆炸。建樹方式:如果兩個原子能量之差剛好是一個光子的能量,那麼連邊這樣問題就變成了求最大獨立集。方程就不在寫了。。。具體看程序


#include <cstdio>
#include <cstring>
#include <map>
#include <vector>

using std::map ;
using std::vector ;
#define maxn 205

map<int , int> hash ;
int node[maxn] ;
int diff[maxn] ;
vector<int> G[maxn] ;
int  dp[maxn][2] ;
bool vis[maxn] ;
int n , m ;

void read(){
	hash.clear() ;
	for(int i = 0 ; i <= n ; i ++){
		G[i].clear() ;
	}
	memset(dp , 0 , sizeof(dp)) ;
	memset(vis , 0 , sizeof(vis)) ;
	for(int i = 1 ; i <= n ; i ++){
	 	int a ;
		scanf("%d" , &a) ;
		hash[a] = i ;
		node[i] = a ;
	}
	for(int i = 1 ; i <= m ; i ++){
		scanf("%d" , &diff[i]) ;
	}
}

inline int max(int x , int y){
	return x > y ? x : y ;
}

void dfs(int v , int f){
    for(int i = 0 ; i != G[v].size() ; i ++){
		int u = G[v][i] ;
		if(u == f)
			continue ;
        dfs(u , v) ;
        dp[v][0] += max(dp[u][1] , dp[u][0]) ;
        dp[v][1] += dp[u][0] ;
	}
	dp[v][1] += node[v] ;
}
void solve(){
	//build the tree
	for(int i = 1 ; i <= n ; i ++){
		for(int j = 1 ; j <= m ; j ++){
			if(hash.count( node[i] + diff[j] )){
				G[i].push_back(hash[ node[i] + diff[j] ]) ;
			}
			if(hash.count( node[i] - diff[j] )){
				G[i].push_back(hash[ node[i] - diff[j] ]) ;
			}
		}
	}
	dfs(1 , -1) ;
	printf("%d\n" , max( dp[1][0] , dp[1][1] ) ) ;
}

int main(){
	while(scanf("%d%d" , &n , &m) , n + m){
		read() ;
		solve();
	}
	return 0 ;
}



發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章