bzoj1487 [HNOI2009]无归岛

Description


Neverland是个神奇的地方,它由一些岛屿环形排列组成,每个岛上都生活着之中与众不同的物种。但是这些物种都有一个共同的生活习性:对于同一个岛 上的任意两个生物,他们有且仅有一个公共朋友,即对同一岛上的任意两个生物a和b有且仅有一个生物c既是a的朋友也是b的朋友,当然某些岛上也可能会只有 一个生物孤单地生活着。这一习性有一个明显的好处,当两个生物发生矛盾的时候,他们可以请那个唯一的公共朋友来裁决谁对谁错。

另外,岛与岛之间也有交流,具体来说,每个岛都会挑选出一个最聪明的生物做代表,然后这个生物与他相邻的两个岛的代表成为朋友。

不行的是,A世界准备入侵Neverland,作为Neverland的守护 者,Lostmonkey想知道在一种比较坏的情况下Never的战斗力。因为和朋友并肩作战,能力会得到提升,所以Lostmonkey想知道在不选出 一对朋友的情况下Neverland的最大战斗力。即选出一些生物,且没有一对生物是朋友,并且要求它们的战斗力之和最大。

Input

第 一行包含用空格隔开的两个整数n和m,分别表示Neverland的生物种数和朋友对数。接下来的m行描述所有朋友对,具体来说,每行包含用空格隔开的两 个整数a和b,表示生物a和生物b是朋友(每对朋友只出现一次)。第m+2行包含用空格隔开的n个整数,其中第i个整数表示生物i的战斗力Ai。输入数据 保证4<=n<=100000,1<=a,b<=n,1<=m<=200000,-1000<=Ai& lt;=1000.

Output

 

仅包含一个整数,表示满足条件的最大战斗力。

Sample Input



6 7
1 2
2 3
3 4
4 1
3 6
3 5
5 6
20 10 30 15 20 10

Sample Output


50

【样例说明】

有四个岛,生物1在1号岛,生物2在2号岛,生物3、5、6在3号岛,生物4在4号岛。

HINT

NeverLand这个单词在“小飞侠彼得潘”中译为梦幻岛,在这却成为无归岛,真是汗啊.

 

正解:仙人掌$DP$。

和小c的独立集是一样的:http://www.cnblogs.com/wfj2048/p/6641693.html

 

 1 //It is made by wfj_2048~
 2 #include <algorithm>
 3 #include <iostream>
 4 #include <complex>
 5 #include <cstring>
 6 #include <cstdlib>
 7 #include <cstdio>
 8 #include <vector>
 9 #include <cmath>
10 #include <queue>
11 #include <stack>
12 #include <map>
13 #include <set>
14 #define inf (1<<30)
15 #define N (100010)
16 #define il inline
17 #define RG register
18 #define ll long long
19 #define File(s) freopen(s".in","r",stdin),freopen(s".out","w",stdout)
20 
21 using namespace std;
22 
23 struct edge{ int nt,to; }g[400010];
24 
25 int head[N],fa[N],dep[N],dfn[N],low[N],vis[N],val[N],f[2][N],ff[2][N],n,m,num,cnt;
26 
27 il int gi(){
28     RG int x=0,q=1; RG char ch=getchar();
29     while ((ch<'0' || ch>'9') && ch!='-') ch=getchar();
30     if (ch=='-') q=-1,ch=getchar();
31     while (ch>='0' && ch<='9') x=x*10+ch-48,ch=getchar();
32     return q*x;
33 }
34 
35 il void insert(RG int from,RG int to){
36     g[++num]=(edge){head[from],to},head[from]=num; return;
37 }
38 
39 il void dp(RG int x,RG int rt,RG int dep,RG int tot){
40     if (dep==tot) return; RG int v;
41     for (RG int i=head[x];i;i=g[i].nt){
42     v=g[i].to; if (fa[v]!=x || !vis[v]) continue;
43     dp(v,rt,dep+1,tot),ff[1][x]+=ff[0][v];
44     if (v==rt) ff[0][x]+=ff[0][v];
45     else ff[0][x]+=max(ff[0][v],ff[1][v]);
46     }
47     if (x==rt) ff[1][x]=0; return;
48 }
49 
50 il void circle(RG int rt,RG int x){
51     RG int tot=dep[x]-dep[rt]+1;
52     ff[0][rt]=f[0][rt],ff[1][rt]=f[1][rt],vis[rt]=1;
53     for (RG int i=x;i!=rt;i=fa[i])
54     ff[0][i]=f[0][i],ff[1][i]=f[1][i],vis[i]=1;
55     dp(rt,rt,1,tot);
56     RG int res1=ff[0][rt],res2=ff[1][rt];
57     ff[0][rt]=f[0][rt],ff[1][rt]=f[1][rt];
58     for (RG int i=x;i!=rt;i=fa[i])
59     ff[0][i]=f[0][i],ff[1][i]=f[1][i];
60     dp(rt,x,1,tot);
61     f[0][rt]=max(f[0][rt],max(res1,ff[0][rt]));
62     f[1][rt]=max(f[1][rt],max(res2,ff[1][rt]));
63     for (RG int i=x;i!=rt;i=fa[i]) vis[i]=0;
64     vis[rt]=0; return;
65 }
66 
67 il void dfs(RG int x,RG int p){
68     fa[x]=p,dep[x]=dep[p]+1,f[1][x]=val[x];
69     dfn[x]=low[x]=++cnt; RG int v;
70     for (RG int i=head[x];i;i=g[i].nt){
71     v=g[i].to; if (v==p) continue;
72     if (!dfn[v]) dfs(v,x),low[x]=min(low[x],low[v]);
73     else low[x]=min(low[x],dfn[v]);
74     if (dfn[x]<low[v]) f[1][x]+=f[0][v],f[0][x]+=max(f[0][v],f[1][v]);
75     }
76     for (RG int i=head[x];i;i=g[i].nt){
77     v=g[i].to; if (v==p) continue;
78     if (fa[v]!=x && dfn[x]<dfn[v]) circle(x,v);
79     }
80     return;
81 }
82 
83 il void work(){
84     n=gi(),m=gi();
85     for (RG int i=1,x,y;i<=m;++i){
86     x=gi(),y=gi();
87     insert(x,y),insert(y,x);
88     }
89     for (RG int i=1;i<=n;++i) val[i]=gi();
90     dfs(1,0); printf("%d",max(f[0][1],f[1][1])); return;
91 }
92 
93 int main(){
94     File("c");
95     work();
96     return 0;
97 }

 

posted @ 2017-03-29 21:00  wfj_2048  阅读(270)  评论(0编辑  收藏  举报