首先我们知道,对于这张图,我们可以枚举坍塌的是哪个点,对于每个坍塌的点,最多可以将图分成若干个不连通的块,这样每个块我们可能需要一个出口才能满足题目的要求,枚举每个坍塌的点显然是没有意义的,我们只需要每个图的若干个割点,这样除去割点的图有若干个块,我们可以求出只与一个割点相连的块,这些块必须要一个出口才能满足题目的要求,每个块内有块内个数种选法,然后将所有满足一个割点相连的块的点数连乘就行了。

  对于每个与一个割点相连的块必须建出口可以换一种方式理解,我们将每个块看做一个点,那么算上割点之后,这张图就变成了一颗树,只有叶子节点我们需要建立出口,因为对于非叶子节点我们不论断掉哪个点我们都有另一种方式相连,这里的叶子节点就是与一个割点相连的块。

  最后还有个特判,就是对于一个双连通图,我们至少需要选取两个点作为出口,因为如果就选一个,可能该点为坍塌点,这时我们就任选两个点就行了,方案数为点数*(点数-1)>>1。

  反思:最开始的时候求只与一个割点相连的块的计算的时候割点计算重复了,后来没有割点的时候的特判没有加,最后的时候发现这道题需要开long long,开了之后忘记改输出的通配符,改了之后输出2的时候应该是2ll,对C++的使用还不够熟悉。

/**************************************************************
Problem: 2730
User: BLADEVIL
Language: C++
Result: Accepted
Time:40 ms
Memory:2956 kb
****************************************************************/ //By BLADEVIL
#include <cstdio>
#include <cstring>
#define maxn 50010 using namespace std; int n;
int last[maxn],pre[maxn],other[maxn];
int dfn[maxn],low[maxn],cut[maxn],vis[maxn],size[maxn],num[maxn],flag[maxn],fuck[maxn];
int l,time;
long long ans1,ans2,task; void getmin(int &x,int y)
{if (y<x) x=y;}
void connect(int x,int y)
{
pre[++l]=last[x];
last[x]=l;
other[l]=y;
} void dfs(int x,int fa)
{
low[x]=dfn[x]=++time;
int q,p,cnt=;
for (q=last[x];q;q=pre[q])
{
p=other[q];
if (p==fa) continue;
if (!dfn[p])
{
dfs(p,x); cnt++;
getmin(low[x],low[p]);
if (dfn[x]<=low[p]&&fa!=-) cut[x]=;
} else getmin(low[x],dfn[p]);
}
if (fa==-&&cnt>) cut[x]=;
} void make(int x,int fa)
{
int p;
for (int q=last[x];q;q=pre[q])
{
p=other[q];
if (p==fa||cut[p]) continue;
if (!vis[p]) vis[p]=vis[x],make(p,x);
}
} void solve()
{
int m=n; n=;
while (m--)
{
int x,y;
scanf("%d%d",&x,&y);
connect(x,y); connect(y,x);
n=(x>n)?x:n;
n=(y>n)?y:n;
fuck[x]=fuck[y]=;
}
for (int i=;i<=n;i++) if (!dfn[i]) dfs(i,-);
//for (int i=1;i<=n;i++) if (cut[i]) printf("%d ",i);
for (int i=;i<=n;i++) if (!(vis[i]||cut[i])) vis[i]=i,make(i,-);
//for (int i=1;i<=n;i++) printf("%d ",vis[i]); printf("\n");
for (int i=;i<=n;i++) if (vis[i]) size[vis[i]]++;
for (int i=;i<=n;i++)
if (cut[i])
{
memset(flag,,sizeof flag);
for (int q=last[i];q;q=pre[q])
if (!flag[vis[other[q]]]) flag[vis[other[q]]]=,num[vis[other[q]]]++;
}
//for (int i=1;i<=n;i++) printf("%d %d %d\n",i,size[i],num[i]);
for (int i=;i<=n;i++)
if (num[i]==) ans1++,ans2*=size[i];
if (!ans1)
{
ans2=;
for (int i=;i<=n;i++)
if (fuck[i]) ans2++;
}
if (!ans1)
printf("Case %lld: %lld %lld\n",task,2ll,ans2*(ans2-)>>); else
printf("Case %lld: %lld %lld\n",task,ans1,ans2);
} void clear()
{
time=l=ans1=0ll; ans2=1ll;
memset(last,,sizeof last);
memset(dfn,,sizeof dfn);
memset(low,,sizeof low);
memset(cut,,sizeof cut);
memset(vis,,sizeof vis);
memset(size,,sizeof size);
memset(num,,sizeof num);
memset(fuck,,sizeof fuck);
} int main()
{
scanf("%d",&n);
while (n)
{
task++;
clear();
solve();
scanf("%d",&n);
}
return ;
}

bzoj 2730 割点的更多相关文章

  1. BZOJ 2730:[HNOI2012]矿场搭建(割点+连通块)

    [HNOI2012]矿场搭建 Description 煤矿工地可以看成是由隧道连接挖煤点组成的无向图.为安全起见,希望在工地发生事故时所有挖煤点的工人都能有一条出路逃到救援出口处.于是矿主决定在某些挖 ...

  2. BZOJ 2730 矿场搭建 Tarjan求割点

    思路: Tarjan求出来点双&割点 判一判就行了 //By SiriusRen #include <stack> #include <cstdio> #include ...

  3. BZOJ 2730: [HNOI2012]矿场搭建( tarjan )

    先tarjan求出割点.. 割点把图分成了几个双连通分量..只需dfs找出即可. 然后一个bcc有>2个割点, 那么这个bcc就不用建了, 因为一定可以走到其他救援出口. 只有一个割点的bcc就 ...

  4. 【刷题】BZOJ 2730 [HNOI2012]矿场搭建

    Description 煤矿工地可以看成是由隧道连接挖煤点组成的无向图.为安全起见,希望在工地发生事故时所有挖煤点的工人都能有一条出路逃到救援出口处.于是矿主决定在某些挖煤点设立救援出口,使得无论哪一 ...

  5. bzoj 2730: [HNOI2012]矿场搭建

    #include<cstdio> #include<cstring> #include<iostream> #define M 508 using namespac ...

  6. 【BZOJ 2730】 [HNOI2012]矿场搭建

    Description 煤矿工地可以看成是由隧道连接挖煤点组成的无向图.为安全起见,希望在工地发生事故时所有挖煤点的工人都能有一条出路逃到救援出口处.于是矿主决定在某些挖煤点设立救援出口,使得无论哪一 ...

  7. BZOJ 2730 矿场搭建

    割点 割点以外的点坍塌不影响其他人逃生,因为假设我们任取两个个非割点s建立救援站,非割点的任意点坍塌,我们都可以从割点走到一个救援出口. 所以我们只考虑割点坍塌的情况. 我们可以先找出图中所有的割点. ...

  8. [BZOJ 2730][HNOI 2012] 矿场搭建

    2730: [HNOI2012]矿场搭建 Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 2113  Solved: 979[Submit][Statu ...

  9. bzoj 2730: [HNOI2012]矿场搭建——tarjan求点双

    Description 煤矿工地可以看成是由隧道连接挖煤点组成的无向图.为安全起见,希望在工地发生事故时所有挖煤点的工人都能有一条出路逃到救援出口处.于是矿主决定在某些挖煤点设立救援出口,使得无论哪一 ...

随机推荐

  1. css那些事儿4 背景图像

    background:背景颜色,图像,平铺方式,大小,位置 能够显示背景区域即为盒子模型的填充和内容部分,其中背景图像将会覆盖背景颜色.常见的水平或垂直渐变颜色背景通常使用水平或垂直渐变的背景图像在水 ...

  2. 3dContactPointAnnotationTool开发日志(二二)

      昨天是实现了显示GameObject子GameObject的选项卡功能,今天就是要让statusPanel可以控制它们的位置.旋转和缩放了.   没什么难的,对应选项卡绑定上对应的物体或子物体即可 ...

  3. Linux文件传输FTP详解

    ftp命令用来设置文件系统相关功能.ftp服务器在网上较为常见,Linux ftp命令的功能是用命令的方式来控制在本地机和远程机之间传送文件,这里详细介绍Linux ftp命令的一些经常使用的命令,相 ...

  4. 【EF】Entity Framework Core 2.0 特性介绍和使用指南

    阅读目录 前言 获取和使用 新特性 项目升级和核心API变化 下一步计划 遗憾的地方 回到目录 前言 这是.Net Core 2.0生态生态介绍的最后一篇,EF一直是我喜欢的一个ORM框架,随着版本升 ...

  5. Runtime之字典转模型实战

    Runtime之字典转模型实战 先来看看怎么使用Runtime给模型类赋值 iOS开发中的Runtime可谓是功能强大,同时Runtime使用起来也是非常灵活的,今天博客的内容主要就是使用到一丁点的R ...

  6. 【bzoj1593】[Usaco2008 Feb]Hotel 旅馆 线段树区间合并

    题目描述 奶牛们最近的旅游计划,是到苏必利尔湖畔,享受那里的湖光山色,以及明媚的阳光.作为整个旅游的策划者和负责人,贝茜选择在湖边的一家著名的旅馆住宿.这个巨大的旅馆一共有N (1 <= N & ...

  7. P1297 [国家集训队]单选错位

    题目背景 原 <网线切割>请前往P1577 题目描述 gx和lc去参加noip初赛,其中有一种题型叫单项选择题,顾名思义,只有一个选项是正确答案.试卷上共有n道单选题,第i道单选题有ai个 ...

  8. springboot2.0 集成elasticsearch,实现检索、分页、排序

    springboot整合es的方式: transport方式(7.0弃用,8.0移除) spring-data(完全当做数据库来用,无法全部支持es,内部也是基于transport,包装后使用非常简单 ...

  9. Git的安装与使用(一)

    闲来无事写了个小demo,想上传到GitHub上,发现得使用git进行上传,所以得先了解下git . 1.git是什么 分布式版本控制器 2.svn与git的区别 svn:是集中式的版本控制系统,版本 ...

  10. [洛谷P3979]遥远的国度

    题目大意:有一棵$n$个点的树,每个点有一个点权,有三种操作: $1\;x:$把根变成$x$ $2\;u\;v\;x:$把路径$u->v$上的点权改为$x$ $3\;x:$询问以$x$为根的子树 ...