[TJOI 2017] 도시 나무 dp+나무의 직경+나무의 중심
문제풀이: 가장 긴 체인을 가장 짧게 하기 위해 가장자리를 수정합니다.각 변을 열거하면 분명히 나무를 두 개의 연결 블록으로 나눌 수 있다. 그러면 가장 긴 체인은 두 개의 연결 블록의 직경일 수도 있고, 두 개의 연결 블록을 연결하는 중심, 즉 두 개의 나무를 연결하는 반경+열거의 변길이일 수도 있다.트리 dp로 구할 수 있습니다.
지름의 경우:
void getd(int x,int &ans){
for(int i=h[x];i;i=data[i].nxt){
int y=data[i].to;int c=data[i].w;if(vis[y]) continue;
vis[y]=1;getd(y,ans);
if(dp[y][0]+c>dp[x][0]){//
dp[x][1]=dp[x][0];son[x]=y;
dp[x][0]=dp[y][0]+c;
}else if(dp[y][0]+c>dp[x][1]){//
dp[x][1]=dp[y][0]+c;
}
}
ans=max(ans,dp[x][0]+dp[x][1]);
}
중심과 반지름의 경우:
void getr(int x,int from,int &ans){
ans=min(ans,max(dp[x][0],from));
for(int i=h[x];i;i=data[i].nxt){
int y=data[i].to;int c=data[i].w;
if(!vis[y]) continue;
vis[y]=0;
if(son[x]==y) getr(y,max(dp[x][1],from)+c,ans);
else getr(y,max(dp[x][0],from)+c,ans);
}
}
#include
#define inf (1<<30)-1
using namespace std;
const int N=5500;
int dp[N][2];
int n,len=1;
struct E{
int to,w,nxt;
}data[N<<1];
int u[N],v[N],val[N],h[N],son[N];
bool vis[N];
int d1,d2,r1,r2,ans;
inline int rd(){
int x=0;int f=1;char s=getchar();
while(!isdigit(s)) f=(s=='-'?-1:f),s=getchar();
while(isdigit(s)) x=(x<<1)+(x<<3)+s-'0',s=getchar();
return x*f;
}
inline void ins(int x,int y,int w){
data[++len].to=y;data[len].w=w;data[len].nxt=h[x];h[x]=len;
data[++len].to=x;data[len].w=w;data[len].nxt=h[y];h[y]=len;
}
inline void clear(){
memset(dp,0,sizeof dp);
memset(vis,0,sizeof vis);
memset(son,0,sizeof son);
}
void getd(int x,int &ans){
for(int i=h[x];i;i=data[i].nxt){
int y=data[i].to;int c=data[i].w;if(vis[y]) continue;
vis[y]=1;getd(y,ans);
if(dp[y][0]+c>dp[x][0]){//
dp[x][1]=dp[x][0];son[x]=y;
dp[x][0]=dp[y][0]+c;
}else if(dp[y][0]+c>dp[x][1]){
dp[x][1]=dp[y][0]+c;
}
}
ans=max(ans,dp[x][0]+dp[x][1]);
}
void getr(int x,int from,int &ans){
ans=min(ans,max(dp[x][0],from));
for(int i=h[x];i;i=data[i].nxt){
int y=data[i].to;int c=data[i].w;
if(!vis[y]) continue;
vis[y]=0;
if(son[x]==y) getr(y,max(dp[x][1],from)+c,ans);
else getr(y,max(dp[x][0],from)+c,ans);
}
}
int main(){
//freopen("city.in","r",stdin);
n=rd();
for(int i=1;i
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
알고리즘 1000 개 노크 #2. Longest common substringsProblem Solution DP (다이나믹 프로그래밍) 중에서 고전적인 문제입니다. 두 문자열을 S1과 S2, 각각의 길이를 M, N으로 설정합니다. 총당으로 S1에서 모든 부분 문자열을 추출하고, 그것들이 S2...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.