首页 > 其他分享 >396. 矿场搭建

396. 矿场搭建

时间:2022-11-21 17:59:10浏览次数:68  
标签:low cnt 挖煤 矿场 int dcc ++ 396 搭建

题目链接

396. 矿场搭建

煤矿工地可以看成是由隧道连接挖煤点组成的无向图。

为安全起见,希望在工地发生事故时所有挖煤点的工人都能有一条出路逃到救援出口处。

于是矿主决定在某些挖煤点设立救援出口,使得无论哪一个挖煤点坍塌之后,其他挖煤点的工人都有一条道路通向救援出口。

请写一个程序,用来计算至少需要设置几个救援出口,以及不同最少救援出口的设置方案总数。

输入格式

输入文件有若干组数据,每组数据的第一行是一个正整数 \(N\),表示工地的隧道数。

接下来的 \(N\) 行每行是用空格隔开的两个整数 \(S\) 和 \(T\),表示挖煤点 \(S\) 与挖煤点 \(T\) 由隧道直接连接。

注意,每组数据的挖煤点的编号为 \(1 \sim Max\),其中 \(Max\) 表示由隧道连接的挖煤点中,编号最大的挖煤点的编号,可能存在没有被隧道连接的挖煤点。

输入数据以 \(0\) 结尾。

输出格式

每组数据输出结果占一行。

其中第 \(i\) 行以 Case i: 开始(注意大小写,Casei 之间有空格,i: 之间无空格,: 之后有空格)。

其后是用空格隔开的两个正整数,第一个正整数表示对于第 \(i\) 组输入数据至少需要设置几个救援出口,第二个正整数表示对于第 \(i\) 组输入数据不同最少救援出口的设置方案总数。

输入数据保证答案小于 \(2^{64}\),输出格式参照以下输入输出样例。

数据范围

\(1 \le N \le 500\),
\(1 \le Max \le 1000\)

输入样例:

9
1  3
4  1
3  5
1  2
2  6
1  5
6  3
1  6
3  2
6
1  2
1  3
2  4
2  5
3  6
3  7
0

输出样例:

Case 1: 2 4
Case 2: 4 1

解题思路

缩点,点双连通分量

针对割点的缩点,是指将所有割点先独立起来,然后将所有的点双连通分量(其包含若干个割点)向对应的割点建边

本题要求在删除某个点其余所有点都可以到达出口点,求最少的出口点的数量和方案数,不妨先按割点缩点,这样会形成一棵树,可以知道,度数为 \(1\) 的节点上必须要设置一个出口点,否则因为如果其父亲节点或根节点的唯一一个儿子节点被删除时该节点对应原图的所有节点就到达不了其他出口点,而对于那些度数大于 \(1\) 的节点来说无论删除哪一个节点来说其都可以达到其他的某个出口点,而对于那些,另外如果树中只有一个节点,可能本就是孤立点,显然要在其上面设置一个出口点,否则说明没有割点,其必须要设置两个出口点,因为如果被删除的点正好是出口点的话,其他点也可以到达另外一个出口点

  • 时间复杂度:\(O(n+m)\)

代码

// Problem: 矿场搭建
// Contest: AcWing
// URL: https://www.acwing.com/problem/content/398/
// Memory Limit: 64 MB
// Time Limit: 1000 ms
// 
// Powered by CP Editor (https://cpeditor.org)

// %%%Skyqwq
#include <bits/stdc++.h>
 
//#define int long long
#define help {cin.tie(NULL); cout.tie(NULL);}
#define pb push_back
#define fi first
#define se second
#define mkp make_pair
using namespace std;
 
typedef long long LL;
typedef pair<int, int> PII;
typedef pair<LL, LL> PLL;
 
template <typename T> bool chkMax(T &x, T y) { return (y > x) ? x = y, 1 : 0; }
template <typename T> bool chkMin(T &x, T y) { return (y < x) ? x = y, 1 : 0; }
 
template <typename T> void inline read(T &x) {
    int f = 1; x = 0; char s = getchar();
    while (s < '0' || s > '9') { if (s == '-') f = -1; s = getchar(); }
    while (s <= '9' && s >= '0') x = x * 10 + (s ^ 48), s = getchar();
    x *= f;
}

const int N=1005;
int n,m;
int h[N],ne[N],e[N],idx;
int timestamp,dfn[N],low[N],dcc_cnt,stk[N],top;
vector<int> dcc[N];
bool cut[N];
int root;
void add(int a,int b)
{
	e[idx]=b,ne[idx]=h[a],h[a]=idx++;
}
void tarjan(int x)
{
	dfn[x]=low[x]=++timestamp;
	stk[++top]=x;
	if(h[x]==-1&&x==root)
	{
		dcc[++dcc_cnt].pb(x);
		return ;
	}
	int cnt=0;
	for(int i=h[x];~i;i=ne[i])
	{
		int j=e[i];
		if(!dfn[j])
		{
			tarjan(j);
			low[x]=min(low[x],low[j]);
			if(dfn[x]<=low[j])
			{
				cnt++;
				if(root!=x||cnt>1)cut[x]=true;
				dcc_cnt++;
				int y;
				do
				{
					y=stk[top--];
					dcc[dcc_cnt].pb(y);
				}while(y!=j);
				dcc[dcc_cnt].pb(x);
			}
		}
		else
			low[x]=min(low[x],dfn[j]);
	}
}
int main()
{
    int T=1;
    while(cin>>m,m)
    {
    	for(int i=1;i<=dcc_cnt;i++)dcc[i].clear();
    	timestamp=dcc_cnt=top=n=idx=0;
    	memset(h,-1,sizeof h);
    	memset(dfn,0,sizeof dfn);
    	memset(cut,0,sizeof cut);
    	for(int i=1;i<=m;i++)
    	{
    		int x,y;
    		cin>>x>>y;
    		n=max(n,x),n=max(n,y);
    		add(x,y),add(y,x);
    	}
    	for(root=1;root<=n;root++)
    		if(!dfn[root])tarjan(root);
    	int res1=0;
    	unsigned long long res2=1;
    	for(int i=1;i<=dcc_cnt;i++)
    	{
    		int cnt=0;
    		for(int j:dcc[i])cnt+=cut[j];
    		if(cnt==0)
    		{
    		    if(dcc[i].size()>1)
    		        res1+=2,res2*=dcc[i].size()*(dcc[i].size()-1)/2;
    		    else
    		        res1++;
    		}
    		else if(cnt==1)res1++,res2*=dcc[i].size()-1;
    	}
    	printf("Case %d: %d %llu\n",T++,res1,res2);
    }
    return 0;
}

标签:low,cnt,挖煤,矿场,int,dcc,++,396,搭建
From: https://www.cnblogs.com/zyyun/p/16912133.html

相关文章

  • Windows搭建Git服务器
    Windows如何搭建Git服务器1、安装java环境(1)下载安装java注意(java的版本需要在1.7及以上)(2)配置java的环境变量(3)检验java环境是否安装成功2、下载安装Gitblit(1)下载地......
  • 从零到一搭建基础架构(6)-让你的服务组件化
    Hello,这里是爱Coding,爱Hiphop,爱喝点小酒的AKA柏炎。本篇是手把手搭建基础架构专栏的第六篇,......
  • 如何像我这样创建一个酷炫且能赚钱的网站(使用宝塔安装WordPress搭建子比主题)
    ​3!2!1!上链接:​​code.haiyong.site/​​不瞒大家说,自我这个新网站创建以来已经赚了几百块钱,虽然不多,但每天的饭钱省了,当然我的初衷不是为了赚钱,只是觉得这个网站比较酷炫,搭......
  • Windows下使用VSCode搭建IDA Python脚本开发环境
    由于本人是VSCode的重度沉迷用户,需要写代码时总会想起这个软件,因此选择在VSCode中搭建IDAPython的开发环境本文适用的环境如下:1.操作系统windows2.Python33.IDAPro......
  • Python3.10 的开发环境的搭建
    安装下载Python3.10或者其他版本:DownloadPython|Python.org如果Windows操作系统下载,默认是下载64位操作系统的exe安装包:python-3.10.0-amd64.exe双击安装......
  • Haproxy搭建web集群
    一.常见的web集群调度器1、目前常见的web集群调度器分为软件和硬件2、软件通常使用开源的LVS、Haproxy、Nginx​LVS性能最好,但搭建复杂。Nginx并发量,性能低于Haproxy......
  • window,一键搭建文件服务器
    之前局域网内共享文件,总是选用飞秋,或者开放win文件共享(无密码坑挺多)等方式,最近静思极动;1.本机有python环境,2.进入要共享的文件,3.地址栏输入:cmd,4.进入dos交互页,输入p......
  • Linux 搭建Apache(httpd)服务
    简介:ApacheHTTPServer是开源软件项目,基于标准的HTTP网络协议提供的网页浏览服务,http是Apache服务器的主程序,它是一个独立的后台进程。1.安装A.安装httpd服务:yun......
  • XtraBackup 搭建从库的一般步骤及 XtraBackup 8.0 的注意事项
    搭建从库,本质上需要的只是一个一致性备份集及这个备份集对应的位置点信息。之前介绍的几个备份工具(MySQL中如何选择合适的备份策略和备份工具)均可满足。这里,我们重点看看......
  • GitHub + Hexo 搭建个人博客网站
    一、准备工作1.GitHub+Hexo的优势Hexo提供现成的模板和模块;github的pages功能提供免费的服务器,零成本搭建属于自己的博客。2.需要了解的网站github,开源代码......