zoukankan      html  css  js  c++  java
  • 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 }
  • 相关阅读:
    EF框架学习
    JS DOM---Chapter 1-4
    ASP.NET页面运行机制以及请求处理流程
    cookie 与 session
    C#中的委托delegate 与 事件 event
    【转】属性与字段的区别
    使用InternalsVisibleTo给assembly添加“友元assembly”
    SQL Server 常用函数和日期操作
    C#中的get 和 set方法
    清晰易懂的Numpy入门教程
  • 原文地址:https://www.cnblogs.com/wfj2048/p/6641740.html
Copyright © 2011-2022 走看看