zoukankan      html  css  js  c++  java
  • BZOJ4316 小C的独立集

    BZOJ4316 小C的独立集

    传送门

    BZOJ萎了所以我就放了darkbzoj的链接

    题解

    考虑求的是仙人掌的最大独立集,我们不需要建出圆方树.还是设(f_{u,0/1})表示(u)点选/不选在(u)子树内的最大独立集.

    • 对于圆点之间的连边,考虑直接转移.
    • 对于方点,等于是一个环,这个环上面的转移等于是钦定(u)选什么,然后把环遍历一遍.

    代码

    #include<stdio.h>
    #include<stdlib.h>
    #include<string.h>
    #include<math.h>
    #include<algorithm>
    #include<queue>
    #include<iostream>
    #include<set>
    #include<map>
    using namespace std;
    #define mp make_pair
    #define ll long long
    #define re register
    typedef pair<int,int> pii;
    #define file(a) freopen(a".in","r",stdin);freopen(a".out","w",stdout)
    inline int gi()
    {
    	int f=1,sum=0;char ch=getchar();
    	while(ch>'9'||ch<'0'){if(ch=='-')f=-1;ch=getchar();}
    	while(ch>='0'&&ch<='9'){sum=(sum<<3)+(sum<<1)+ch-'0';ch=getchar();}
    	return f*sum;
    }
    const int N=200010;
    int n,m,front[N],cnt,f[N][2],fa[N],low[N],dfn[N],Time;
    struct node{int to,nxt;}e[N<<1];
    void Add(int u,int v){e[++cnt]=(node){v,front[u]};front[u]=cnt;}
    void solve(int u,int v)
    {
    	int s0,s1,f0=0,f1=0;
    	for(int i=v;i!=u;i=fa[i])
    	{
    		s0=f0+f[i][0];s1=f1+f[i][1];
    		f0=max(s0,s1);f1=s0;
    	}
    	f[u][0]+=f0;
    	f0=0,f1=-1e9;
    	for(int i=v;i!=u;i=fa[i])
    	{
    		s0=f0+f[i][0];s1=f1+f[i][1];
    		f0=max(s0,s1);f1=s0;
    	}
    	f[u][1]+=f1;
    }
    void dfs(int u,int ff)
    {
    	dfn[u]=low[u]=++Time;fa[u]=ff;f[u][0]=0;f[u][1]=1;
    	for(int i=front[u];i;i=e[i].nxt)
    	{
    		int v=e[i].to;if(v==ff)continue;
    		if(!dfn[v]){dfs(v,u);low[u]=min(low[u],low[v]);}
    		else low[u]=min(low[u],dfn[v]);
    		if(dfn[u]<low[v])
    		{
    			f[u][0]+=max(f[v][0],f[v][1]);
    			f[u][1]+=f[v][0];
    		}
    	}
    	for(int i=front[u];i;i=e[i].nxt)
    	{
    		int v=e[i].to;if(v==ff)continue;
    		if(fa[v]!=u&&dfn[u]<dfn[v])solve(u,v);
    	}
    }
    int main()
    {
    	n=gi();m=gi();
    	for(int i=1;i<=m;i++)
    	{
    		int u=gi(),v=gi();
    		Add(u,v);Add(v,u);
    	}
    	dfs(1,0);
    	printf("%d
    ",max(f[1][0],f[1][1]));
    	return 0;
    }
    
  • 相关阅读:
    【JavaSE】成员方法快速入门和方法的调用机制原理
    HarmonyOS实战—实现注册登录和修改密码页面
    苹果CMS自动定时采集教程
    HarmonyOS实战—统计按钮点击次数
    HarmonyOS实战—点击更换随机图片
    C语言 main 函数
    C语言 vprintf 函数和 printf 函数区别
    C语言 vprintf 函数
    C语言 va_start / va_end / va_arg 自定义 printf 函数
    C语言 va_arg 宏
  • 原文地址:https://www.cnblogs.com/fexuile/p/13025503.html
Copyright © 2011-2022 走看看