zoukankan      html  css  js  c++  java
  • BZOJ 1487 无归岛

    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的战斗力(A_{i})

    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

    Hint

    输入数据保证(4 le n le 100000)(1 le a,b le n)(1 le m le 200000)(-1000 le Ai le 1000)

    BZOJ 1040

    #include<iostream>
    #include<cstdio>
    #include<cstdlib>
    #include<cstring>
    using namespace std;
    
    #define inf (1<<30)
    #define maxn 200010
    int n,m,cnt,cir[maxn],w[maxn],fa[maxn],side[maxn];
    int dfn[maxn],low[maxn],toit[maxn*2],next[maxn*2];
    int f[maxn][2],g[maxn][2],ans;
    
    inline int read()
    {
        int x=0,f=1;char ch=getchar();
        while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
        while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
        return x*f;
    }
    
    inline void add(int a,int b) { next[++cnt] = side[a]; toit[cnt] = b; side[a] = cnt; } 
    
    inline void ins(int a,int b) { add(a,b); add(b,a); }
    
    inline void dp(int root,int last)
    {
    	int nn = 0;
    	while (last != root) cir[++nn] = last,last = fa[last];
    	cir[++nn] = root;
    	for (int i = 1;i <= nn;++i) g[cir[i]][0] = f[cir[i]][0],g[cir[i]][1] = f[cir[i]][1];
    	g[root][1] = inf;
    	for (int i = nn-1;i;--i)
    	{
    		g[cir[i]][0] += min(g[cir[i+1]][0],g[cir[i+1]][1]);
    		g[cir[i]][1] += g[cir[i+1]][0];
    	}
    	f[root][0] = min(g[cir[1]][0],g[cir[1]][1]);
    	for (int i = 1;i <= nn;++i) g[cir[i]][0] = f[cir[i]][0],g[cir[i]][1] = f[cir[i]][1];
    	g[root][0] = inf;
    	for (int i = nn-1;i;--i)
    	{
    		g[cir[i]][0] += min(g[cir[i+1]][0],g[cir[i+1]][1]);
    		g[cir[i]][1] += g[cir[i+1]][0];
    	}
    	f[root][1] = g[cir[1]][0];
    }
    
    inline void dfs(int now)
    {
    	dfn[now] = low[now] = ++cnt;
    	f[now][0] = w[now];
    	for (int i = side[now];i;i = next[i])
    		if (toit[i] != fa[now])
    		{
    			if (fa[toit[i]] == now) continue;
    			if (!dfn[toit[i]]) fa[toit[i]] = now,dfs(toit[i]);
    			low[now] = min(low[now],low[toit[i]]);
    			if (low[toit[i]] > dfn[now])
    			{
    				f[now][0] += min(f[toit[i]][0],f[toit[i]][1]);
    				f[now][1] += f[toit[i]][0];
    			}
    		}
    	for (int i = side[now];i;i = next[i])
    		if (toit[i] != fa[now] && dfn[toit[i]] > dfn[now] && fa[toit[i]] != now)
    			dp(now,toit[i]);
    }
    
    int main()
    {
    	freopen("1487.in","r",stdin);
    	freopen("1487.out","w",stdout);
    	n = read(); m = read();
    	for (int i = 1;i <= m;++i) ins(read(),read());
    	for (int i = 1;i <= n;++i) w[i] =read(),ans += w[i];
    	for (int i = 1;i <= n;++i)
    		if (!dfn[i]) cnt = 0,dfs(i),ans -= min(f[i][0],f[i][1]);
    	printf("%d",ans);
    	fclose(stdin); fclose(stdout);
    	return 0;
    }
    
  • 相关阅读:
    Linked List Cycle leetcode java (链表检测环)
    Remove Duplicates from Sorted List II leetcode java
    Remove Duplicates from Sorted List leetcode java
    Merge Two Sorted Lists leetcode java
    Swap Nodes in Pairs leetcode java
    Median of Two Sorted Array leetcode java
    阿里云最便宜的四种域名注册
    nohup和&后台运行,进程查看及终止
    ipv6转ipv4 NAT64与DNS64基本原理概述
    ros使用pppoe拨号获取ipv6,并且下发IPV6的dns到客户机win7
  • 原文地址:https://www.cnblogs.com/mmlz/p/4321954.html
Copyright © 2011-2022 走看看