UVALive 5135 Mining Your Own Business

题意:

一些隧道组成矿井  现在要修建尽量少的逃生通道  使得无论哪里发生事故  所有人均能逃出  求方案数

思路:

这道题比较容易联想到割点  因为只有这种点出事矿井才会不连通  那么首先就找出所有割点

分析最少要建几个逃生通道  那当然是每个连通块各一个  因此需要把求出连通块顶点数之积

最后考虑特殊情况  没有割点  那么随便两个地方建就好了  不能建一个  万一就那里出事了呢…

代码:

#include<cstdio>
#include<cstring>
#include<algorithm>
#include<set>
using namespace std;
#define N 50010
typedef long long LL;

int m,n,tot,t,ans1,res,idx;
int head[N],dfn[N],low[N],cut[N],vis[N];
struct edge
{
    int v,flag,next;
}ed[N*2];
LL ans2;
set<int> next;

void add(int u,int v)
{
    ed[tot].v=v; ed[tot].flag=0; ed[tot].next=head[u]; head[u]=tot++;
}

void tarjan(int u,int fa)
{
	int i,v,son=0;
	dfn[u]=low[u]=++idx;
	for(i=head[u];~i;i=ed[i].next)
	{
		v=ed[i].v;
		if(ed[i].flag||dfn[v]>=dfn[u]) continue;
		ed[i].flag=ed[i^1].flag=1;
		if(dfn[v]==-1)
		{
			son++;
			tarjan(v,u);
			low[u]=min(low[u],low[v]);
			if(u!=fa&&dfn[u]<=low[v]) cut[u]=1;
		}
		else low[u]=min(low[u],dfn[v]);
	}
	if(u==fa&&son>1) cut[u]=1;
}

void dfs(int u)
{
    int i,v;
    res++;
    vis[u]=1;
    for(i=head[u];~i;i=ed[i].next)
    {
        v=ed[i].v;
        if(cut[v]) next.insert(v);
        if(!cut[v]&&!vis[v]) dfs(v);
    }
}

int main()
{
	int i,u,v;
	while(~scanf("%d",&m))
	{
	    if(!m) break;
	    tot=n=idx=0;
	    memset(head,-1,sizeof(head));
	    memset(dfn,-1,sizeof(dfn));
	    memset(cut,0,sizeof(cut));
	    memset(vis,0,sizeof(vis));
	    for(i=1;i<=m;i++)
        {
            scanf("%d%d",&u,&v);
            n=max(n,u);
            n=max(n,v);
            add(u,v);
            add(v,u);
        }
		tarjan(1,1);
		ans1=0;
		ans2=1;
		for(i=1;i<=n;i++)
        {
            if(!cut[i]&&!vis[i])
            {
                res=0;
                next.clear();
                dfs(i);
                if(next.size()==1)
                {
                    ans1++;
                    ans2*=res;
                }
            }
        }
        if(ans1==0)
        {
            ans1=2;
            ans2=(LL)(n)*(n-1)/2;
        }
        printf("Case %d: ",++t);
		printf("%d %lld\n",ans1,ans2);
	}
	return 0;
}
时间: 2024-08-26 18:25:43

UVALive 5135 Mining Your Own Business的相关文章

UVALive - 5135 Mining Your Own Business(双连通分量)

题目大意:有N个矿井 ,由一些隧道连接起来,现在要修建尽量少的安全通道,使得无论哪里发生事故,所有人均能逃出,求建的最少的安全通道数量和方案数 解题思路:建安全通道的话,肯定不能建在割顶,因为割顶如果崩塌了,割顶所连接的双连通分量内的点就跑不掉了,还得在双连通分量里面再建点(上述为双连通分量内部只有一个割顶的情况),这样不划算,还不如直接在里面建点 如果一个双连通分量的内部割顶有多个的话,那么在这个双连通分量里面就可以不用建安全通道了,因为一个割顶崩塌了,还有其他点可以连向外面,所以,只考虑内部

UVALive 5135 Mining Your Own Business 双连通分量 2011final

题意:n条隧道由一些点连接而成,其中每条隧道链接两个连接点.任意两个连接点之间最多只有一条隧道.任务就是在这些连接点中,安装尽量少的太平井和逃生装置,使得不管哪个连接点倒塌,工人都能从其他太平井逃脱,求最少安装数量和方案. 思路:其实本题就相当于在一张无向图中,涂尽量少的黑点,使得任意删除哪个点,每个连通分量至少有一个黑点.因为不同的连通分量最多只有一个公共点,那一定是割点.可以发现,涂黑割点是不划算的,而且在 一个点-双连通分量中涂黑两个黑点也是不划算的.所以只有当点-双连通分量只有一个割点时

【LA】5135 Mining Your Own Business

[算法]点双连通分量 [题解]详见<算法竞赛入门竞赛入门经典训练指南>P318-319 细节在代码中用important标注. #include<cstdio> #include<algorithm> #include<vector> #include<stack> #include<cstring> using namespace std; const int maxm=50010; struct edge{int u,v,from

LA 5135 Mining Your Own Business

求出 bcc 后再……根据大白书上的思路即可. 然后我用的是自定义的 stack 类模板: 1 #include<cstdio> 2 #include<cstring> 3 #include<vector> 4 //#include<stack> 5 #include<stdexcept> 6 #include<algorithm> 7 using namespace std; 8 typedef long long LL; 9 co

UVALive 5135 Mining Your Own Bussiness【tarjan点双】

LINK1 LINK2 题目大意 给你一个无向连通图,让你给一些点染上黑色,需要满足染色之后,断开任意一个节点,要满足任意一个联通块中剩下的节点中至少有一个黑点 思路 一开始想的是把每一个点双联通分量都把除了割点的size乘上 然后发现随手卡掉 然后发现一下性质 首先所有相邻点双联通分量一定有公共的割点 如果一个双联通分量里面只包含了一个割点,那么如果断掉这个割点那么这个双联通分量就被孤立了 所以这样的双联通分量至少选择一个点 然后如果一个双联通分量有大于等于两个割点,就算一个被割掉了另外一边至

UVA 1108 - Mining Your Own Business(双连通分量)

UVA 1108 - Mining Your Own Business 题目链接 题意:给定一个连通图,设置一个些安全点,使得其他任意一些节点崩塌后,其他点都能到一个安全点,问安全点最小数量和情况数 思路: #include <cstdio> #include <cstring> #include <vector> #include <stack> #include <map> using namespace std; const int N =

HDU 3844 Mining Your Own Business

Mining Your Own Business Time Limit: 1000ms Memory Limit: 32768KB This problem will be judged on HDU. Original ID: 384464-bit integer IO format: %I64d      Java class name: Main John Digger is the owner of a large illudium phosdex mine. The mine is m

hdu 3844 Mining Your Own Business (点双连通分量)

Mining Your Own Business Time Limit: 6000/3000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 1392    Accepted Submission(s): 219 Problem Description John Digger is the owner of a large illudium phosdex mine. The m

UVALive5135 - Mining Your Own Business(BCC)

题目链接 题意:n条隧道由一些点连接而成,其中每条隧道链接两个连接点.任意两个连接点之间最多只有一条隧道.任务就是在这些连接点中,安装尽量少的太平井和逃生装置,使得不管哪个连接点倒塌,工人都能从其他太平井逃脱,求最少安装数量和方案. 思路:其实本题就相当于在一张无向图中,涂尽量少的黑点,使得任意删除哪个点,每个连通分量至少有一个黑点.因为不同的连通分量最多只有一个公共点,那一定是割点.可以发现,涂黑割点是不划算的,而且在一个点-双连通分量中涂黑两个黑点也是不划算的.所以只有当点-双连通分量只有一