1. 程式人生 > >[BZOJ1040][ZJOI2008]騎士(環套樹dp)

[BZOJ1040][ZJOI2008]騎士(環套樹dp)

zoj 以及 rip type 接下來 描述 discus des 之間

1040: [ZJOI2008]騎士

Time Limit: 10 Sec Memory Limit: 162 MB
Submit: 5816 Solved: 2263
[Submit][Status][Discuss]

Description

  Z國的騎士團是一個很有勢力的組織,幫會中匯聚了來自各地的精英。他們劫富濟貧,懲惡揚善,受到社會各
界的贊揚。最近發生了一件可怕的事情,邪惡的Y國發動了一場針對Z國的侵略戰爭。戰火綿延五百裏,在和平環境
中安逸了數百年的Z國又怎能抵擋的住Y國的軍隊。於是人們把所有的希望都寄托在了騎士團的身上,就像期待有一
個真龍天子的降生,帶領正義打敗邪惡。騎士團是肯定具有打敗邪惡勢力的能力的,但是騎士們互相之間往往有一
些矛盾。每個騎士都有且僅有一個自己最厭惡的騎士(當然不是他自己),他是絕對不會與自己最厭惡的人一同出
征的。戰火綿延,人民生靈塗炭,組織起一個騎士軍團加入戰鬥刻不容緩!國王交給了你一個艱巨的任務,從所有
的騎士中選出一個騎士軍團,使得軍團內沒有矛盾的兩人(不存在一個騎士與他最痛恨的人一同被選入騎士軍團的
情況),並且,使得這支騎士軍團最具有戰鬥力。為了描述戰鬥力,我們將騎士按照1至N編號,給每名騎士一個戰
鬥力的估計,一個軍團的戰鬥力為所有騎士的戰鬥力總和。

Input

  第一行包含一個正整數N,描述騎士團的人數。接下來N行,每行兩個正整數,按順序描述每一名騎士的戰鬥力
和他最痛恨的騎士。

Output

  應包含一行,包含一個整數,表示你所選出的騎士軍團的戰鬥力。

Sample Input

3
10 2
20 3
30 1

Sample Output

30

HINT

N ≤ 1 000 000,每名騎士的戰鬥力都是不大於 1 000 000的正整數。

Source

[Submit][Status][Discuss]

每個點有且僅有一個出邊,說明每個連通分量(有向連通)都是有且僅有一個環,以及環邊的樹(樹根必定在環上),這就是基環外向樹問題。

感覺有點像仙人球的超弱化版?直接對一個每遍歷過的點,找到所在的連通分量的環,然後

 1 #include<cstdio>
 2 #include<algorithm>
 3 #define rep(i,l,r) for (int i=l; i<=r; i++)
 4 #define For(i,x) for (int i=h[x],k; i; i=nxt[i])
 5 typedef long long ll;
 6 using namespace std;
 7 
 8 const int N=2000100,inf=1000000000;
 9 int n,cnt,rt,fa[N],val[N],vis[N],to[N],nxt[N],h[N];
10 ll f[N][2
],ans; 11 void add(int u,int v){ to[++cnt]=v; nxt[cnt]=h[u]; h[u]=cnt; } 12 13 void dfs(int x){ 14 vis[x]=1; f[x][0]=0; f[x][1]=val[x]; 15 For(i,x) if ((k=to[i])!=rt) 16 dfs(k),f[x][0]+=max(f[k][1],f[k][0]),f[x][1]+=f[k][0]; 17 else f[k][1]=-inf; 18 } 19 20 void find(int x){ 21 vis[x]=1; rt=x; 22 while (!vis[fa[rt]]) rt=fa[rt],vis[rt]=1; 23 dfs(rt); ll t=max(f[rt][0],f[rt][1]); 24 vis[rt]=1; rt=fa[rt]; dfs(rt); ans+=max(t,max(f[rt][0],f[rt][1])); 25 } 26 27 int main(){ 28 freopen("P2607.in","r",stdin); 29 freopen("P2607.out","w",stdout); 30 scanf("%d",&n); 31 rep(i,1,n) scanf("%d",&val[i]),scanf("%d",&fa[i]),add(fa[i],i); 32 rep(i,1,n) if (!vis[i]) find(i); 33 printf("%lld\n",ans); 34 return 0; 35 }

[BZOJ1040][ZJOI2008]騎士(環套樹dp)