【BZOJ4316】小C的独立集

来源:互联网 发布:mysql 数据库log文件 编辑:程序博客网 时间:2024/05/21 11:24

Description

图论小王子小C经常虐菜,特别是在图论方面,经常把小D虐得很惨很惨。
这不,小C让小D去求一个无向图的最大独立集,通俗地讲就是:在无向图中选出若干个点,这些点互相没有边连接,并使取出的点尽量多。
小D虽然图论很弱,但是也知道无向图最大独立集是npc,但是小C很仁慈的给了一个很有特点的图: 图中任何一条边属于且仅属于一个简单环,图中没有重边和自环。小C说这样就会比较水了。
小D觉得这个题目很有趣,就交给你了,相信你一定可以解出来的。
Input

第一行,两个数n, m,表示图的点数和边数。
第二~m+1行,每行两个数x,y,表示x与y之间有一条无向边。
Output

输出这个图的最大独立集。
Sample Input

5 6

1 2

2 3

3 1

3 4

4 5

3 5
Sample Output

2

HINT

100% n <=50000, m<=60000

Source

一开始觉得一脸不可做..后来发现是个仙人掌图..可以直接仙人掌DP
但是忘了仙人掌缩点姿势了..又看了一发hillan的缩点..
然后直接dp.f[i][0/1]表示整个图里点i选和不选,g[i][0/1]表示在某个环里点i选和不选,然后整体DP,遇到环单独进去DP

#include<iostream>#include<cstdio>#include<cstring>#include<cmath>#include<algorithm>#define MAXN 100010#define GET (ch>='0'&&ch<='9')using namespace std;int n,m,u,v,cnt,top;inline void in(int &x){    char ch=getchar();x=0;    while (!GET)    ch=getchar();    while (GET) x=x*10+ch-'0',ch=getchar();}struct edge {   int to; edge *next; }e[MAXN<<1],*prev[MAXN];inline void insert(int u,int v) {   e[++top].to=v;e[top].next=prev[u];prev[u]=&e[top];  }int f[MAXN][2],g[MAXN][2];int sta[MAXN],tp;int low[MAXN],dfn[MAXN],deep[MAXN],fa[MAXN];void dp(int x,int to){    for (sta[0]=x,sta[tp=1]=to;sta[tp]!=x;sta[++tp]=fa[sta[tp-1]]);    int t1,t2;g[0][0]=g[0][1]=0;    for (int i=1;i<=tp;i++)        g[i][1]=g[i-1][0]+f[sta[i]][1],        g[i][0]=max(g[i-1][0],g[i-1][1])+f[sta[i]][0];    t1=g[tp][0];g[0][0]=-1;    for (int i=1;i<=tp;i++)        g[i][1]=g[i-1][0]+f[sta[i]][1],        g[i][0]=max(g[i-1][0],g[i-1][1])+f[sta[i]][0];    t2=g[tp][1];    f[x][1]=t2;f[x][0]=t1;}void dfs(int x){    low[x]=dfn[x]=++cnt;f[x][1]=1;f[x][0]=0;    for (edge *i=prev[x];i;i=i->next)        if (i->to!=fa[x])        {            if (deep[i->to])    low[x]=min(low[x],dfn[i->to]);            else            {                fa[i->to]=x;deep[i->to]=deep[x]+1;                dfs(i->to);                if (low[i->to]>dfn[x])  f[x][1]+=f[i->to][0],f[x][0]+=max(f[i->to][1],f[i->to][0]);                low[x]=min(low[x],low[i->to]);            }        }    for (edge *i=prev[x];i;i=i->next)        if (i->to!=fa[x]&&low[i->to]==dfn[x]&&deep[i->to]!=deep[x]+1)   dp(x,i->to);}int main(){    for (in(n),in(m);m;m--) in(u),in(v),insert(u,v),insert(v,u);    deep[1]=1;fa[1]=1;dfs(1);    printf("%d\n",max(f[1][0],f[1][1]));}
1 0
原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 宝宝发烧40多度怎么办 7岁宝宝发烧了怎么办 宝宝反复发烧39度怎么办 一岁半宝宝反复发烧39度怎么办 七岁发烧38度怎么办 小孩一直37度1怎么办 婴儿一直37度多怎么办 1岁半高烧39度怎么办 反复发烧39度多怎么办 孩子不爱喝水怎么办%3f 8岁儿童不爱喝水怎么办 儿子14岁了不爱说话怎么办 我孩子长得老慢怎么办 老公嫌你烦了怎么办 2岁宝宝吃饭不嚼怎么办 2岁宝宝挑食厌食怎么办 孩子不爱和家长交流怎么办 孩子发烧在医院查不出病因怎么办 宝宝乳牙长歪了怎么办 两岁宝宝不爱吃水果怎么办 两岁宝宝不吃水果怎么办 一岁的宝宝上火了怎么办 吃水果嘴唇肿了怎么办 二岁宝宝不爱吃饭怎么办 小婴儿便秘但不爱喝水怎么办 宝宝只吃水果不吃饭怎么办 一岁宝宝不喜欢吃水果怎么办 1岁宝宝不吃水果怎么办 一岁半宝宝吃水果拉肚子怎么办 大人发烧了怎么办如何退烧 怀孕后不爱吃水果怎么办 不敢吃水果了怕虫怎么办 宝宝发烧38度不出汗怎么办 1岁宝宝喜欢含饭怎么办 3岁宝宝喜欢含饭怎么办 孩子咳嗽发烧怎么办最有效 孩子咳嗽打哈切流鼻涕发烧怎么办 孩子香蕉吃多了怎么办 80多岁老人发烧怎么办 小孩香蕉吃多了怎么办 7个月宝宝缺钙怎么办