hdu 4635 Strongly connected (tarjan)

hdu 4635 Strongly connected (tarjan)

大家好,又见面了,我是全栈君。

题意:给一个n个顶点m条弧的简单有向图(无环无重边),求最多能够加入多少条弧使得加入后的有向图仍为简单有向图且不是一个强连通图。假设给的简单有向图本来就是强连通图,那么输出-1.


分析:

1.用tarjan算法求出强连通分量的个数,假设个数为1,那么输出-1,结束,否则运行2

2.如果将一些强连通分量合并为有n1个顶点简单全然图1,而将剩下的强连通分量合并为n2个顶点的简单全然图2,跨这两个简单全然图的弧的方向仅仅能是单向的,如果m1为全然图1内部的弧的数量,m2为为全然图2内部的弧的数量。m3为跨这两个简单全然图的弧的数量,那么

 ans=n1*(n1-1)-m1+n2*(n2-1)-m2+n1*n2-m3  —————————————————-1式

 n1+n2=n                                                            —————————————————-2式

 m1+m2+m3=m                                                 —————————————————-3式

 n*n=(n1+n2)(n1+n2)=n1*n1+n2*n2+2*n1*n2 —————————————————–4式

所以

ans=n*n-m-n-n1*n2=n*n-m-n-n1*(n-n1)

ans要最大,所以n1*(n-n1)要最小。同一时候要跨图1。图2的弧要单向,

所以在跨图1,图2的弧要单向的情况下。n1尽量小。


代码:
#include<stdio.h>#include<stdlib.h>#include<string.h>#define MAX 100005#define INF 1<<30using namespace std;typedef struct ArcNode{    int adjvex;//该弧所指向的顶点的位置    struct ArcNode * nextarc;//指向下一条弧的指针} ArcNode;typedef struct VNode{    int vertex;    //int In_deg,Out_deg;    int belong;    ArcNode * firstarc;} VNode;VNode V[MAX];int DFN[MAX],Stack[MAX],low[MAX];int top,index,bcnt;bool instack[MAX];long long n,m;int Min;int cnt;int k;int edge[MAX][2];void init(){    int a,b;    ArcNode * p;    for(int i=1; i<=n; i++)    {        V[i].vertex=i;        //V[i].In_deg=V[i].Out_deg=0;        V[i].firstarc =NULL;    }    for(int i=0; i<m; i++)    {        scanf("%d%d",&a,&b);       // V[a].Out_deg++;       // V[b].In_deg++;       edge[i][0]=a;       edge[i][1]=b;        p=(ArcNode*)malloc(sizeof(ArcNode));        p->adjvex =b;        p->nextarc =V[a].firstarc ;        V[a].firstarc =p;    }}void DFS_tarjan(int i){    int j;    ArcNode * p;    DFN[i]=low[i]=++index;    Stack[++top]=i;    instack[i]=true;    p=V[i].firstarc ;    while(p!=NULL)    {        j=p->adjvex;        if(!DFN[j])        {            DFS_tarjan(j);            if(low[j]<low[i])//Low(u)为u的子树可以追溯到的最早的栈中节点的次序号                low[i]=low[j];        }        else if(instack[j]&&DFN[j]<low[i])//Low(u)为u可以追溯到的最早的栈中节点的次序号            low[i]=DFN[j];        p=p->nextarc;//    }    if(DFN[i]==low[i])    {        bcnt++;        cnt=0;        int INDEG=0;        int OUTDEG=0;        do        {            j=Stack[top--];//出栈,j是为该强连通分量中一个顶点            instack[j]=false;            //INDEG+=V[j].In_deg;            //OUTDEG+=V[j].Out_deg;            V[j].belong=bcnt;            cnt++;        }        while(i!=j);        for(int kkk=0;kkk<m;kkk++)        {            if(V[edge[kkk][0]].belong==bcnt&&V[edge[kkk][1]].belong!=bcnt)            {                OUTDEG++;            }            if(V[edge[kkk][0]].belong!=bcnt&&V[edge[kkk][1]].belong==bcnt)                INDEG++;        }        if(Min>cnt&&(INDEG==0||OUTDEG==0))        {            Min=cnt;        }    }}void FREE(){    ArcNode * p;    ArcNode * q;    for(int i=1; i<=n; i++)    {        p=V[i].firstarc;        while(p!=NULL)        {            q=p;            p=p->nextarc;            free(q);        }    }}void solve(){    int i;    top=index=bcnt=0;    memset(DFN,0,sizeof(DFN));    memset(instack,false,sizeof(instack));    for(i=1; i<=n; i++)    {        if(!DFN[i])            DFS_tarjan(i);    }    //printf("%d\n",bcnt);    FREE();    if(bcnt==1)    {        printf("Case %d: -1\n",k);        return;    }    long long ans=n*n-n-m-(Min*(n-Min));    //printf("%d\n",Min);    printf("Case %d: %lld\n",k,ans);}int main(){    int t;    scanf("%d",&t);    for(k=1; k<=t; k++)    {        scanf("%lld%lld",&n,&m);        Min=INF;        init();        solve();    }    return 0;}

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/115821.html原文链接:https://javaforall.net

赞 (0)
全栈程序员-站长的头像全栈程序员-站长


相关推荐

  • 如何删除对象的某个属性(对象属性方法是什么)

    基于React钩子的轻量级状态管理解决方案Ice-store的简单使用优点极简API:只有5个API,简单上手,使用方便,不需要学习Redux里的各种概念。ReactHooks:拥抱Hooks的使用体验,同时也是基于ReactHooks实现。集成异步状态:记录异步action的执行状态,简化view组件中对于loading与error状态的渲染…

    2022年4月13日
  • Mysql性能优化一:SQL语句性能优化

    Mysql性能优化一:SQL语句性能优化

    2021年11月7日
  • 一起谈.NET技术,关于大型ASP.NET应用系统的架构—如何做到高性能高可伸缩性…

    一起谈.NET技术,关于大型ASP.NET应用系统的架构—如何做到高性能高可伸缩性…

    2021年8月13日
  • html表单提交_html表单标签有哪些

    html表单提交_html表单标签有哪些1.表单属性设置<form>标签表示表单标签,定义整体的表单区域action属性设置表单数据提交地址method属性设置表单提交的方式,一般有“GET”方式和“POST”方式,不区分大小写2.表单元素属性设置name属性设置表单元素的名称,该名称是提交数据时的参数名value属性设置表单元素的值,该值是提交数据时参数名所对应的值3.示例代码<formaction=”https://www.baidu.com”method=”GET”>

    2022年9月26日
  • win10开机“正在准备自动修复”,且无法修复你的电脑「建议收藏」

    win10开机“正在准备自动修复”,且无法修复你的电脑「建议收藏」昨天一顿操作,先是快速启动,后来又觉得快速启动没用又关掉了,第二天过来,发现电脑开不起来了,进到里面怎么自动修复不得行,网上大多数的答案是重装,经过半天努力摸索,终于修好了,原理就不想深究了。准备:一个U盘,并且制作PE系统。1、电脑的系统启动设置在U盘启动,进入PE系统2、打开分区工具DiskGenius点硬盘点重建主引导记录MBR(一般在开始菜单都有)3、再返…

    2022年4月20日
  • Eclipse SVN冲突详细解决方案「建议收藏」

    Eclipse SVN冲突详细解决方案「建议收藏」大家一起开发,难免有时会同时修改同一个文件,这样就要学会解决冲突。当大家更新代码,发现以下情况的时候,就说明你的修改的文件和服务器的文件产生了冲突(一般是别人也改了同一个文件)。1)和服务器有冲突的文件:2)点击Update以后,如果出现以下情况(出现四个文件),就说明需要解决冲突。如何解决冲突:出现文件冲突的时候:你有四个选择:1以我修改的为准,不管服务

    2022年10月14日

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号