码迷,mamicode.com
首页 > 其他好文 > 详细

poj3713 Transferring Sylla 枚举+tarjan判割点

时间:2018-07-14 16:28:20      阅读:167      评论:0      收藏:0      [点我收藏+]

标签:tle   rri   scan   用例   pen   oid   删除   dfs   scanf   

其实就是判断是否为三连通图

三连通图指的是去掉3个点就不连通的图,但是并没有直接求三连通的算法。著名的Tarjan算法可以求解连通和割点,再枚举删除一个点就能达到三连通的目的。

先看用例2,是由用例1去掉一条边而变成非三连通图的:

技术分享图片

至少造成了2和3非三连通:

技术分享图片

我们来思考如何推导出2和3非三连通,假设从上图中删除了节点0,通过Tarjan算法,我们可以发现节点1是割点:

 

技术分享图片

那么只需删除从3到割点和从3到我们枚举删除的节点0的两条边,就可以将3和2分割开来:

技术分享图片

才删除了两条边2和3就不连通了,这个图显然不是三连通图。

 

技术分享图片
#include<stdio.h>
#include<algorithm>
#include<string.h>
using namespace std;
const int maxn = 20010;
int cnt,flag,times,del,root;
int head[maxn],low[maxn],dfn[maxn];
struct no
{
    int v,next;
}Eg[2*maxn];
void init( )
{
    cnt=0;
    memset(head,-1,sizeof(head));
}
void add(int form,int to)
{
    Eg[cnt].v=to;Eg[cnt].next=head[form];head[form]=cnt++;
}
void dfs(int u,int fa)
{
    if(flag)
    return ;
    int tot=0;
    low[u] = dfn[u] = ++times;
    for(int i=head[u] ; i!=-1 ; i=Eg[i].next)
    {
        int v=Eg[i].v;
        if(v==fa||v==del)
        continue;
        if(!dfn[v])
        {
            tot++;
            dfs(v,u);
            low[u]=min(low[u],low[v]);
            //判断割点
            if((u==root&&tot>1)||(u!=root&&low[v]>=dfn[u]))
                flag=1;
        }
        else
        low[u]=min(low[u],dfn[v]);
    }
}
int main( )
{
    int n,m;
    while(scanf("%d%d",&n,&m)!=EOF)
    {
        if(n==0&&m==0)
            break;
    init();
    for(int i=0 ; i<m ; i++)
    {
        int u,v;
        scanf("%d%d",&u,&v);
        add(u,v);
        add(v,u);
    }
    flag=0;
    for(int i=0 ; i<n ; i++)
    {
        del = i ; times = 0;
        memset(dfn,0,sizeof(dfn));
        root = 0;
        if(del==0)
        root=1;
        dfn[del] = 1;
        dfs(root,-1);
        for(int j=0 ; j<n ; j++)
        {
            if(!dfn[j])
            {
                flag=1;
                break;
            }
        }
        if(flag)
            break;
    }
    if(flag)
        puts("NO");
    else
        puts("YES");
    }
    return 0;

}
View Code

 

poj3713 Transferring Sylla 枚举+tarjan判割点

标签:tle   rri   scan   用例   pen   oid   删除   dfs   scanf   

原文地址:https://www.cnblogs.com/shuaihui520/p/9309461.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!