频道栏目
首页 > 资讯 > 其他 > 正文

Mining Your Own Busine (点-双连通分量)

18-08-01        来源:[db:作者]  
收藏   我要投稿

题意:有一座地下的稀有金属矿由n条隧道和一些连接点组成,其中每条隧道连接两个连接点。任意两个连接点之间最多只有一条隧道。为了降低矿工的危险,你的任务是在一些连接点处安装太平井和相应的逃生装置,使得不管哪个连接点倒塌,不在此连接点的所有矿工都能到达太平井逃生(假定除了倒塌的连接点外,其他隧道和连接点完好无损)。为了节约成本,你应当在尽量少的连接点安装太平井。还要需要计算出太平井的数目最小时的安装方案总数。

分析:本题的模型是:在一个无向图上选择尽量少的点涂黑(对应太平井),使得任意删除一个点后,每个连通分量至少有一个黑点。不难发现,把割顶涂黑是不划算的。进一步分析,当一个点-双连通分量只有一个割顶时才需要涂,而且是任选一个非割顶涂黑即可。两个问题同时解决。
一个特殊情况是整个图没有割顶。此时需要涂两个点,方案总数是V*(V-1)/2,其中V是连接点的个数。

代码:

#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 


using namespace std;

const int maxn =50000+10;

int n,m;
int pre[maxn],iscut[maxn],dfs_clock,bcc_cnt,bccno[maxn];
vector  G[maxn],bcc[maxn];

void init()
{
 dfs_clock=bcc_cnt=0;
memset(pre,0,sizeof(pre));
memset(iscut,0,sizeof(iscut));
memset(bccno,0,sizeof(bccno));
 for(int i=1; i S;

int dfs(int u,int fa)
{
 int lowu = pre[u] =++dfs_clock;
 int child =0;
 for(int i=0; i= pre[u])
{
 iscut[u]=1;
 bcc_cnt++;
 bcc[bcc_cnt].clear();

 for(; ;)
 {
 Edge x=S.top();
 S.pop();
 if(bccno[x.u]!=bcc_cnt)
 {
  bcc[bcc_cnt].push_back(x.u);
  bccno[x.u]=bcc_cnt;
 }

 if(bccno[x.v]!=bcc_cnt)
 {
  bcc[bcc_cnt].push_back(x.v);
  bccno[x.v]=bcc_cnt;
 }

 if(x.u==u&&x.v==v)
  break;
 }
}
  }
  else if(pre[v]
相关TAG标签
上一篇:Java关于标识符与关键字的知识总结
下一篇:关于XML的简介
相关文章
图文推荐

关于我们 | 联系我们 | 广告服务 | 投资合作 | 版权申明 | 在线帮助 | 网站地图 | 作品发布 | Vip技术培训 | 举报中心

版权所有: 红黑联盟--致力于做实用的IT技术学习网站