题目

图论小王子小C经常虐菜,特别是在图论方面,经常把小D虐得很惨很惨。

这不,小C让小D去求一个无向图的最大独立集,通俗地讲就是:在无向图中选出若干个点,这些点互相没有边连接,并使取出的点尽量多。

小D虽然图论很弱,但是也知道无向图最大独立集是npc,但是小C很仁慈的给了一个很有特点的图: 图中任何一条边属于且仅属于一个简单环,图中没有重边和自环。小C说这样就会比较水了。

小D觉得这个题目很有趣,就交给你了,相信你一定可以解出来的。

输入格式

第一行,两个数n, m,表示图的点数和边数。

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

输出格式

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

输入样例

5 6

1 2

2 3

3 1

3 4

4 5

3 5

输出样例

2

提示

100% n <=50000, m<=60000

题解

假设这是一棵树,设\(f[i][0]\)表示\(i\)节点为根,不选\(i\)的最大数量,\(f[i][1]\)表示选择\(i\)的最大数量

转移就很简单了,不选\(i\),儿子可以选可以不选,选了\(i\),儿子必须选

如果是仙人掌的话,就先忽略环上的点,然后单独考虑环的影响传递到最高点

#include<iostream>
#include<cmath>
#include<cstdio>
#include<cstring>
#include<algorithm>
#define LL long long int
#define REP(i,n) for (int i = 1; i <= (n); i++)
#define Redge(u) for (int k = h[u],to; k; k = ed[k].nxt)
#define BUG(s,n) for (int i = 1; i <= (n); i++) cout<<s[i]<<' '; puts("");
using namespace std;
const int maxn = 50005,maxm = 120005,INF = 1000000000;
inline int read(){
int out = 0,flag = 1; char c = getchar();
while (c < 48 || c > 57) {if (c == '-') flag = -1; c = getchar();}
while (c >= 48 && c <= 57) {out = (out << 3) + (out << 1) + c - '0'; c = getchar();}
return out * flag;
}
int n,m,h[maxn],ne = 2;
struct EDGE{int to,nxt;}ed[maxm];
void build(int u,int v){
ed[ne] = (EDGE){v,h[u]}; h[u] = ne++;
ed[ne] = (EDGE){u,h[v]}; h[v] = ne++;
}
int f[maxn][2],fa[maxn],dfn[maxn],low[maxn],cnt;
int c[maxn],ci,g[maxn][2];
void DP(int u,int rt){
ci = 0; int ans1,ans2;
for (int i = u; i != rt; i = fa[i]) c[++ci] = i;
g[u][0] = f[u][0]; g[u][1] = 0;
for (int i = 2; i <= ci; i++){
u = c[i];
if (i == 2) g[u][0] = f[u][0] + g[c[i - 1]][0];
else g[u][0] = f[u][0] + max(g[c[i - 1]][0],g[c[i - 1]][1]);
g[u][1] = f[u][1] + g[c[i - 1]][0];
}
ans1 = g[c[ci]][0];
g[c[1]][0] = f[c[1]][0]; g[c[1]][1] = f[c[1]][1];
for (int i = 2; i <= ci; i++){
u = c[i];
g[u][0] = f[u][0] + max(g[c[i - 1]][0],g[c[i - 1]][1]);
g[u][1] = f[u][1] + g[c[i - 1]][0];
}
ans2 = max(g[c[ci]][1],g[c[ci]][0]);
f[rt][1] += ans1;
f[rt][0] += ans2;
}
void dfs(int u){
dfn[u] = low[u] = ++cnt;
f[u][1] = 1;
Redge(u) if ((to = ed[k].to) != fa[u]){
if (!dfn[to]){
fa[to] = u;
dfs(to);
low[u] = min(low[u],low[to]);
}else low[u] = min(low[u],dfn[to]);
if (low[to] > dfn[u]){
f[u][0] += max(f[to][0],f[to][1]);
f[u][1] += f[to][0];
}
}
Redge(u) if (dfn[to = ed[k].to] > dfn[u] && fa[to] != u)
DP(to,u);
}
int main(){
n = read(); m = read();
while (m--) build(read(),read());
int ans = 0;
REP(i,n) if (!dfn[i]){
dfs(i);
ans += max(f[i][0],f[i][1]);
}
printf("%d\n",ans);
return 0;
}

BZOJ4316 小C的独立集 【仙人掌】的更多相关文章

  1. [BZOJ4316]小C的独立集 仙人掌?

    题目链接 因为xls让我每周模拟一次,然后学习模拟中没有学过的东西.所以就来学圆方树. 本来这道题用不着圆方树,但是圆方树是看yyb的博客学的,他在里面讲一下作为一个引子,所以也来写一下. 首先来Ta ...

  2. 【BZOJ-4316】小C的独立集 仙人掌DP + 最大独立集

    4316: 小C的独立集 Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 57  Solved: 41[Submit][Status][Discuss] ...

  3. BZOJ 4316: 小C的独立集 仙人掌 + 树形DP

    4316: 小C的独立集 Time Limit: 10 Sec  Memory Limit: 128 MB Description 图论小王子小C经常虐菜,特别是在图论方面,经常把小D虐得很惨很惨. ...

  4. 2019.02.07 bzoj4316: 小C的独立集(仙人掌+树形dp)

    传送门 题意:给出一个仙人掌森林求其最大独立集. 思路:如果没有环可以用经典的树形dpdpdp解决. fi,0/1f_{i,0/1}fi,0/1​表示第iii个点不选/选的最大独立集. 然后fi,0+ ...

  5. bzoj4316小C的独立集(dfs树/仙人掌+DP)

    本题有两种写法,dfs树上DP和仙人掌DP. 先考虑dfs树DP. 什么是dfs树?其实是对于一棵仙人掌,dfs后形成生成树,找出非树边(即返祖边),然后dfs后每条返祖边+其所覆盖的链构成了一个环( ...

  6. [BZOJ4316]小C的独立集(圆方树DP)

    题意:求仙人掌图直径. 算法:建出仙人掌圆方树,对于圆点直接做普通的树上DP(忽略方点儿子),方点做环上DP并将值直接赋给父亲. 建图时有一个很好的性质,就是一个方点在邻接表里的点的顺序正好就是从环的 ...

  7. bzoj4316: 小C的独立集

    Description 图论小王子小C经常虐菜,特别是在图论方面,经常把小D虐得很惨很惨. 这不,小C让小D去求一个无向图的最大独立集,通俗地讲就是:在无向图中选出若干个点,这些点互相没有边连接,并使 ...

  8. BZOJ.4316.小C的独立集(仙人掌 DP)

    题目链接 \(Description\) 求一棵仙人掌的最大独立集. \(Solution\) 如果是树,那么 \(f[i][0/1]\) 表示当前点不取/取的最大独立集大小,直接DP即可,即 \(f ...

  9. 【题解】Bzoj4316小C的独立集

    决定要开始学习圆方树 & 仙人掌相关姿势.加油~~ 其实感觉仙人掌本质上还是一棵树,长得也还挺优美的.很多的想法都可以往树的方面上靠,再针对仙人掌的特性做出改进.这题首先如果是在树上的话那么实 ...

随机推荐

  1. RAC数据库后台进程介绍

    在RAC数据库上会比单实例数据库多一些进程,这些进程是RAC特有的,为了实现集群数据库功能而设置的. 10g RAC特有进程:$ ps -ef|grep ora_oracle    4721     ...

  2. IOS CoreData 多表查询(下)

    http://blog.csdn.net/fengsh998/article/details/8123392 在iOS CoreData中,多表查询上相对来说,没有SQL直观,但COREDATA的功能 ...

  3. js倒计时小插件(兼容大部分浏览器)

    精确到天的倒计时 <script language="JavaScript"> <!-- // (c) Henryk Gajewski var urodz= ne ...

  4. phpmyadmin设置不密码,不登录直接进入

    1.config.sample.inc.php改为config.inc.php 2.加入或更改代码: [php] $cfg['Servers'][$i]['auth_type'] = 'config' ...

  5. redis入门指南书中概要

    一.简介 1.redis是一个开源的.高性能的.基于键值对的缓存和存储系统,通过提供多种键值数据类型适应不同场景下的缓存和存储需求,同时redis高级功能能胜任消息队列.任务队列等不同角色. 2.内存 ...

  6. composer安装laravel-u-editor及其使用

    前言  使用的框架是laravel5.1,是composer搭建的,可以直接配置composer,如果不是composer搭建的larave,需要先安装composer,具体安装发放可以参考compo ...

  7. jmeter操作mysql数据库

    1.导入jdbc的jar包,因为jmeter本身不能直接连接mysql,所以需要导入第三方的jar包,来连接mysql 2.创建数据库连接配置,mysql的url.端口号.账号.密码 在JDBC Co ...

  8. nginx url rewrite break和last的区别

    break 将重写的URI作为一个新的URI,在本块中继续处理,将重写后 的地址在当前location块中处理,不会将新的URI转向到其他location块中 last,终止继续在本location块 ...

  9. 动态设置html的title

    使用vue前端框架做,竟然丢弃了很多javascript和html的东西了..动态设置title的方法: 1.使用vue的自定义指令 <div v-title>{{htmltitle}}& ...

  10. JAVA基础篇—Servlet小结

    一.get请求和post请求的区别: 1.get请求是通过url传递参数,post请求是通过请求体传递参数的 2.get请求最多允许传递255个字符,对长度有限制,所以数据比较大的时候我们使用post ...