题目传送门

题意

在一个无向图上选择尽量少的点涂黑,使得删除任意一个点后,每个连通分量里都至少有一个黑点(多组数据)。

正文

观察题意,发现这是个 Tarjan 求点双连通分量的板子。

考虑在求点双连通分量的时候把割点顺便求出来,令第 \(i\) 个点双连通分量的大小为 \(size_i\),然后进行分类讨论:

  • 当第 \(i\) 个点双连通分量中没有割点时,符合题意则需要涂黑两个点,方案总数增加 \(C_{size_i}^2=\frac{size_i!}{{(size_i-2)}!×2!}=\frac{size_i(size_i-1)}{2}\)。

    • 如图,\((1,2,3,4)\) 为本图的点双连通分量,且没有割点,则在 \((1,2,3,4)\) 中任选两个点涂黑。

  • 当第 \(i\) 个点双连通分量中有 \(1\) 个割点时,若符合题意则需要涂黑一个点(不能将割点涂黑),方案总数增加 \(C_{size_i-1}^1=\frac{(size_i-1)!}{{(size_i-2)}!×1!}=size_i-1\)。

    • 如图,\((1,2,6,3,5),(1,4)\) 为本图的两个点双连通分量,且 \(1\) 为本图的割点,则在 \((2,6,3,5),(4)\) 中各任选出一个点涂黑。

  • 当第 \(i\) 个点双连通分量中的割点个数大于 \(1\) 时,不需要涂黑。

    • 如图,点双连通分量 \((2,5,6)\) 中有两个割点,则不需要涂黑。

    • 证明:当割点删除后,可以通过另一个割点达到其他点双连通分量。

代码

#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define sort stable_sort
#define endl '\n'
struct node
{
ll next,to;
}e[400001];
vector<ll>v_dcc[400001];
stack<ll>s;
ll head[400001],dfn[400001],low[400001],cut[400001],cnt,tot,ans;
void add(ll u,ll v)
{
cnt++;
e[cnt].next=head[u];
e[cnt].to=v;
head[u]=cnt;
}
void tarjan(ll x,ll fa)
{
ll i,k=0,son=0;
tot++;
dfn[x]=low[x]=tot;
s.push(x);
for(i=head[x];i!=0;i=e[i].next)
{
if(dfn[e[i].to]==0)
{
tarjan(e[i].to,fa);
low[x]=min(low[x],low[e[i].to]);
if(low[e[i].to]>=dfn[x])
{
son++;
if(x!=fa||son>=2)//求割点
{
cut[x]=1;
}
ans++;
v_dcc[ans].clear();//初始化
v_dcc[ans].push_back(x);
while(e[i].to!=k)
{
k=s.top();
v_dcc[ans].push_back(k);
s.pop();
}
}
}
else
{
low[x]=min(low[x],dfn[e[i].to]);
}
}
}
int main()
{
ll n,m,i,j,u,v,sum=0,num,len,ans1,ans2;
while(cin>>m)
{
if(m==0)
{
break;
}
else
{
n=0;
sum++;
tot=ans=cnt=ans1=0;
ans2=1;
while(s.empty()==0)
{
s.pop();
}
memset(e,0,sizeof(e));//多测不清空,爆零两行泪
memset(low,0,sizeof(low));
memset(dfn,0,sizeof(dfn));
memset(cut,0,sizeof(cut));
memset(head,0,sizeof(head));
for(i=1;i<=m;i++)
{
cin>>u>>v;
n=max(n,max(u,v));//n的个数需要自己求
add(u,v);
add(v,u);
}
for(i=1;i<=n;i++)
{
if(dfn[i]==0)
{
tarjan(i,i);
}
}
for(i=1;i<=ans;i++)
{
num=0;
len=v_dcc[i].size();
for(j=0;j<len;j++)
{
if(cut[v_dcc[i][j]]==1)//判断是否是割点
{
num++;
}
}
if(num==0)//如果没有割点
{
ans1+=2;
ans2*=(len-1)*len/2;
}
if(num==1)//如果有一个割点
{
ans1++;
ans2*=len-1;
}
}
cout<<"Case "<<sum<<": "<<ans1<<" "<<ans2<<endl;
}
}
return 0;
}

后记

三倍经验 luoguP3225 [HNOI2012] 矿场搭建 | SP16185 BUSINESS - Mining your own business | UVA1108 Mining Your Own Business

UVA1108 Mining Your Own Business 题解的更多相关文章

  1. 「题解报告」SP16185 Mining your own business

    题解 SP16185 Mining your own business 原题传送门 题意 给你一个无向图,求至少安装多少个太平井,才能使不管那个点封闭,其他点都可以与有太平井的点联通. 题解 其他题解 ...

  2. UVALive - 5135 - Mining Your Own Business(双连通分量+思维)

    Problem   UVALive - 5135 - Mining Your Own Business Time Limit: 5000 mSec Problem Description John D ...

  3. HDU3844 Mining Your Own Business

    HDU3844 Mining Your Own Business 问题描述John Digger是一个大型illudium phosdex矿的所有者.该矿山由一系列隧道组成,这些隧道在各个大型交叉口相 ...

  4. 【LA】5135 Mining Your Own Business

    [算法]点双连通分量 [题解]详见<算法竞赛入门竞赛入门经典训练指南>P318-319 细节在代码中用important标注. #include<cstdio> #includ ...

  5. UVALive 5135 Mining Your Own Business 双连通分量

    据说这是一道Word Final的题,Orz... 原题链接:https://icpcarchive.ecs.baylor.edu/index.php?option=com_onlinejudge&a ...

  6. UVA5135 Mining Your Own Business ( 无向图双连通分量)

    题目链接 题意:n条隧道由一些点连接而成,其中每条隧道链接两个连接点.任意两个连接点之间最多只有一条隧道.任务就是在这些连接点中,安装尽量少的太平井和逃生装置,使得不管哪个连接点倒塌,工人都能从其他太 ...

  7. HDU 3844 Mining Your Own Business

    首先,如果图本来就是一个点双联通的(即不存在割点),那么从这个图中选出任意两个点就OK了. 如果这个图存在割点,那么我们把割点拿掉后图就会变得支离破碎了.对于那种只和一个割点相连的块,这个块中至少要选 ...

  8. LA 5135 Mining Your Own Business

    求出 bcc 后再……根据大白书上的思路即可. 然后我用的是自定义的 stack 类模板: #include<cstdio> #include<cstring> #includ ...

  9. UVA 1108 - Mining Your Own Business

    刘汝佳书上都给出了完整的代码 在这里理一下思路: 由题意知肯定存在一个或者多个双连通分量: 假设某一个双连通分量有割顶.那太平井一定不能打在割顶上. 而是选择割顶之外的随意一个点: 假设没有割顶,则要 ...

  10. HDU 3844 Mining Your Own Business(割点,经典)

    题意: 给出一个连通图,要求将某些点涂黑,使得无论哪个点(包括相关的边)撤掉后能够成功使得剩下的所有点能够到达任意一个涂黑的点,颜料不多,涂黑的点越少越好,并输出要涂几个点和有多少种涂法. 思路: 要 ...

随机推荐

  1. 如何在Python中的子进程获取键盘输入

    场景:在Python中使用multiprocessing模块的Process创建子进程,试图在子进程中获取键盘输入. 使用input() 在子进程中使用input()会弹出报错信息:EOFError: ...

  2. PMP2023

    敏捷迭代周期过程中的会议 https://blog.csdn.net/xudahai513/article/details/125216704 https://img-blog.csdnimg.cn/ ...

  3. Shell-循环-for-while

  4. [转帖]OceanBase 存储引擎详解

    https://zhuanlan.zhihu.com/p/436485359 作者简介:沈炼,蚂蚁集团技术风险部数据库高级专家毕业于东南大学,2014年以来从事 OceanBase 在蚂蚁的架构工作, ...

  5. [转帖]你应该知道的Shell 脚本的经典十三问

    https://blog.csdn.net/wangzhicheng987/article/details/131031344 1. 为何叫做shell? 我们知道计算机的运作不能离开硬件,但使用者却 ...

  6. [转帖]15分钟了解TiDB

    https://zhuanlan.zhihu.com/p/338947811 由于目前的项目把mysql换成了TiDb,所以特意来了解下tidb.其实也不能说换,由于tidb和mysql几乎完全兼容, ...

  7. [转帖]FIO使用说明

    FIO介绍: FIO是测试IOPS的非常好的工具,用来对磁盘进行压力测试和验证.磁盘IO是检查磁盘性能的重要指标,可以按照负载情况分成照顺序读写,随机读写两大类.FIO是一个可以产生很多线程或进程并执 ...

  8. [转帖] 常见的Socket网络异常场景分析

    https://www.cnblogs.com/codelogs/p/16001770.html 原创:打码日记(微信公众号ID:codelogs),欢迎分享,转载请保留出处. 简介# 在目前微服务的 ...

  9. [转帖]Kdump调试机理详细总结(一)

    https://blog.csdn.net/luckiers/category_11796393.html 一.简介 本文主要讲解Kdump的运行机理,后续两个章节会详细介绍kdump的使用和如何分析 ...

  10. SMFL 教程&个人笔记(2)

    本文大部分来自官方教程的Google翻译 但是加了一点点个人的理解和其他相关知识 转载请注明 原文链接 :https://www.cnblogs.com/Multya/p/16317401.html ...