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

    题目链接

    一句话题意

    求仙人掌上最大独立集


    解析

    考虑先用(tarjan)找出环,然后环内外分别处理.
    其实是用(dfs)序的性质做题.
    (f[u][0])表示不选(u)的最大独立集,(f[u][1])表示选(u)的最大独立集,那么答案是(max(f[1][0],f[1][1]))
    如果我们找到了一条边是桥,那么直接转移.
    如果是环边,就先不转移.
    等到把整个环都找出来之后一起转移.
    由于是环,可以枚举环终点((dfs)序最大的点)是否选,然后做两遍(dp)就好了.答案记录到环的起始点((dfs)序最小的点),然后继续转移即可.

    代码如下

    #include<iostream>
    #include<cstdio>
    #include<algorithm>
    #include<cstring>
    #include<cmath>
    #include<vector>
    #define N (120010)
    #define inf (0x7f7f7f7f)
    #define rg register int
    #define Label puts("NAIVE")
    #define spa print(' ')
    #define ent print('
    ')
    #define rand() (((rand())<<(15))^(rand()))
    typedef long double ld;
    typedef long long LL;
    typedef unsigned long long ull;
    using namespace std;
    inline char read(){
    	static const int IN_LEN=1000000;
    	static char buf[IN_LEN],*s,*t;
    	return (s==t?t=(s=buf)+fread(buf,1,IN_LEN,stdin),(s==t?-1:*s++):*s++);
    }
    template<class T>
    inline void read(T &x){
    	static bool iosig;
    	static char c;
    	for(iosig=false,c=read();!isdigit(c);c=read()){
    		if(c=='-')iosig=true;
    		if(c==-1)return;
    	}
    	for(x=0;isdigit(c);c=read())x=((x+(x<<2))<<1)+(c^'0');
    	if(iosig)x=-x;
    }
    inline char readchar(){
    	static char c;
    	for(c=read();!isalpha(c);c=read())
    	if(c==-1)return 0;
    	return c;
    }
    const int OUT_LEN = 10000000;
    char obuf[OUT_LEN],*ooh=obuf;
    inline void print(char c) {
    	if(ooh==obuf+OUT_LEN)fwrite(obuf,1,OUT_LEN,stdout),ooh=obuf;
    	*ooh++=c;
    }
    template<class T>
    inline void print(T x){
    	static int buf[30],cnt;
    	if(x==0)print('0');
    	else{
    		if(x<0)print('-'),x=-x;
    		for(cnt=0;x;x/=10)buf[++cnt]=x%10+48;
    		while(cnt)print((char)buf[cnt--]);
    	}
    }
    inline void flush(){fwrite(obuf,1,ooh-obuf,stdout);}
    int n,m,fi[N],ne[N],b[N],f[N][2],E;
    int dfn[N],low[N],st[N],top,ind,fa[N];
    void add(int x,int y){ne[++E]=fi[x],fi[x]=E,b[E]=y;}
    void dp(int u,int st){
    	int t0,t1,f0=0,f1=0;
    	for(int i=u;i!=st;i=fa[i]){
    		t0=f0+f[i][0],t1=f1+f[i][1];
    		f0=max(t0,t1),f1=t0;
    	}
    	f[st][0]+=f0;
    	f0=0,f1=-inf;
    	for(int i=u;i!=st;i=fa[i]){
    		t0=f0+f[i][0],t1=f1+f[i][1];
    		f0=max(t0,t1),f1=t0;
    	}
    	f[st][1]+=f1;
    }
    void tarjan(int u,int pre){
    	f[u][1]=1,f[u][0]=0,fa[u]=pre;
    	dfn[u]=low[u]=++ind;
    	for(int i=fi[u];i;i=ne[i]){
    		int v=b[i];
    		if(!dfn[v]){
    			tarjan(v,u);
    			low[u]=min(low[u],low[v]);
    		}
    		else if(v!=pre)low[u]=min(low[u],dfn[v]);
    		if(low[v]>dfn[u])
    		f[u][1]+=f[v][0],f[u][0]+=max(f[v][0],f[v][1]);
    	}
    	for(int i=fi[u];i;i=ne[i])
    	if(fa[b[i]]!=u&&dfn[u]<dfn[b[i]])
    	dp(b[i],u);
    }
    int main(){
    	read(n),read(m);
    	for(int i=1,x,y;i<=m;i++){
    		read(x),read(y);
    		add(x,y),add(y,x);
    	}
    	tarjan(1,0);
    	printf("%d
    ",max(f[1][0],f[1][1]));
    }
    
  • 相关阅读:
    React在componentDidMount里面发送请求
    React 术语词汇表
    React里受控与非受控组件
    React和Vue等框架什么时候操作DOM
    【LeetCode】79. Word Search
    【LeetCode】91. Decode Ways
    【LeetCode】80. Remove Duplicates from Sorted Array II (2 solutions)
    【LeetCode】1. Two Sum
    【LeetCode】141. Linked List Cycle (2 solutions)
    【LeetCode】120. Triangle (3 solutions)
  • 原文地址:https://www.cnblogs.com/Romeolong/p/10057163.html
Copyright © 2011-2022 走看看