一、POJ-1848:Tree
1.1 问题描述
Consider a tree with N vertices, numbered from 1 to N. Add, if it is possible, a minimum number of edges thus every vertex belongs to exactly one cycle.
题目大意:
给出一棵树,现在要往这棵树上加边,使得所有的点都在环中,且每个点只能属于一个环
1.2 问题解决
#include<stdio.h>
#include<vector>
#include<string.h>
#include<algorithm>
using namespace std;
#define N 105
#define INF 10000
vector<int> adj[N*2];
int vis[N];
int dp[N][3];
void dfs(int u)
{
vis[u]=1;
vector<int> ch;
int sum=0,v;
for(int i=0; i<adj[u].size(); i++)
{
v=adj[u][i];
if(vis[v]==0)
{
dfs(v);
ch.push_back(v);
sum+=dp[v][0];
}
}
if(ch.size()==0)
{
dp[u][1]=0;
dp[u][0]=dp[u][2]=INF;
return;
}
dp[u][1]=min(INF,sum);
dp[u][2]=dp[u][0]=INF;
for(int i=0; i<ch.size(); i++)
{
v=ch[i];
dp[u][2]=min(dp[u][2],sum-dp[v][0]+min(dp[v][1],dp[v][2]));
dp[u][0]=min(dp[u][0],sum-dp[v][0]+dp[v][2]+1);
}
for(int i=0; i<ch.size(); i++)
{
v=ch[i];
for(int j=0; j<ch.size(); j++)
{
if(i==j)
continue;
int k=ch[j];
dp[u][0]=min(dp[u][0],sum-dp[v][0]-dp[k][0]+min(dp[v][1],dp[v][2])+min(dp[k][1],dp[k][2])+1);
}
}
}
int main()
{
int n,a,b;
scanf("%d",&n);
for(int i=1; i<n; i++)
{
scanf("%d%d",&a,&b);
adj[a].push_back(b);
adj[b].push_back(a);
}
memset(vis,0,sizeof(vis));
dfs(1);
if(dp[1][0]>=INF)
printf("-1\n");
else
printf("%d\n",dp[1][0]);
return 0;
}
二、Leetcode-383:赋金信
2.1 问题描述
2.2 问题解决
class Solution {
public boolean canConstruct(String ransomNote, String magazine) {
int[] help = new int[26];
for(char c : magazine.toCharArray()){
++help[c - 'a'];
}
for(char c: ransomNote.toCharArray()){
if(--help[c - 'a'] < 0) {
return false;
}
}
return true;
}
}
三、生词
vertices n. 顶点
cycle n. 周期
四、参考文章
- POJ-1848-treedp
- poj1848 树状DP