題面大意:n個人有乙個價值和乙個最恨的人,現在組出乙個隊伍使得價值最大且沒有仇恨關係。
————————————————————
如果我們把被仇恨的人向仇恨他的人連一條有向邊的話,那麼我們不難發現,我們得到的圖將會是若干個基環外向樹(就是乙個環,環上每個點都掛著一棵樹)。
如果沒有環,只有樹的話,那麼顯然就是「沒有上司的舞會」的那道題。
那麼基本思路就沒有變,f[i][0]表示i不選的時候的最大價值,f[i][1]表示i選的時候的最大價值。
我們顯然可以先列舉樹在環上的根,然後將環拆開成樹,對這棵樹進行一遍樹形dp。
但是顯然拆開部分也需要考慮,我們對拆開的邊的另乙個端點也進行一次樹形dp,這樣我們就有了所有的點的真實dp,我們就可以愉快的更新了。
#include#include#include
#include
#include
using
namespace
std;
typedef
long
long
ll;const
int n=1e6+5
;inline
intread()
while(isdigit(ch))x=(x<<3)+(x<<1)+(ch^48),ch=getchar();
return w?-x:x;
}struct
nodeedge[n];
int head[n],fa[n],val[n],num[n],cnt=0
;ll ans,f[n][2];
bool
vis[n];
inline
void add(int u,int
v)void dfs(int
u) }
return;}
inline
void dp(int
u) }
f[rt][
1]=val[rt];
for(int i=head[rt];i;i=edge[i].nxt)
ans+=max(f[rt][0],f[rt][1
]);
return;}
intmain()
for(int i=1;i<=n;i++)
printf(
"%lld\n
",ans);
return0;
}
BZOJ1040 騎士(動態規劃)
bzoj 對於每一組厭惡的關係 顯然是連邊操作 如果是一棵樹的話 很顯然的樹型dp 但是,現在相當於有很多個基環 也就是在一棵樹的基礎上再加了一條邊 這個時候怎麼辦,暴力拆掉基環 拆掉任意一條邊 跑兩遍dp 計算出強制不選兩個點中某乙個的最大值 此時就是這個基環的最大值 不用拆掉所有的邊,因為只要拆...
BZOJ 1040 騎士(樹形DP)
題意 給出乙個圖,只有乙個環。每個點有乙個權值。選出一些點兩兩不相鄰,使得權值最大?思路 1 找到環。dfs,標記訪問,下乙個節點不是父節點但是已被訪問則這條邊就是環上的兩個點。標記這個邊是我們找到的環邊,並將這兩個點的中乙個設定為root,另乙個我們設為node 2 由於root和node不能同時...
BZOJ1040 騎士(動態規劃)
bzoj 對於每一組厭惡的關係 顯然是連邊操作 如果是一棵樹的話 很顯然的樹型 dp 但是,現在相當於有很多個基環 也就是在一棵樹的基礎上再加了一條邊 這個時候怎麼辦,暴力拆掉基環 拆掉任意一條邊 跑兩遍 dp 計算出強制不選兩個點中某乙個的最大值 此時就是這個基環的最大值 不用拆掉所有的邊,因為只...