gym Bridges

来源:互联网 发布:mysql 5.7 json 函数 编辑:程序博客网 时间:2024/06/07 23:19

题目大意:给你一个无向图,问我们最多加一条边使得图的桥的数量最小,输出最小数量

解题思路:先将图缩点,我们就得到一个无环图,然后我们只需找到最长链,将其首尾相连即可减少对多的桥,减少的数量为链的长度,即树的直径。(ps:注释部分为并查集缩点)

代码:

//#pragma comment(linker, "/STACK:1024000000,1024000000")#include<cstdio>#include<cstring>#include<iostream>#include<map>#include<set>#include<stack>#include<vector>#include<queue>#include<cmath>#include<algorithm>using namespace std;#define inf 0x3fffffff//const double pi=acos(-1);typedef long long LL;#define N 100005int low[N],pre[N],scc[N],dfs_clock,scc_cnt;int fa[N];int cnt;int ans;int root;struct node{    int st,en,next;    //bool fg;} e[2*N],e1[2*N];int p[N],num;void init(){    memset(p,-1,sizeof(p));    num=0;}void add(int st,int en){    e[num].st=st;    e[num].en=en;    //e[num].fg=false;    e[num].next=p[st];    p[st]=num++;}int p1[N],num1;void init1(){    memset(p1,-1,sizeof(p1));    num1=0;}void add1(int st,int en){    e1[num1].st=st;    e1[num1].en=en;    e1[num1].next=p1[st];    p1[st]=num1++;}//int Find(int x)//{//    if(fa[x]!=x)//        fa[x]=Find(fa[x]);//    return fa[x];//}//void Union(int u,int v)//{//    int x=Find(u);//    int y=Find(v);//    if(x!=y)//    {//        fa[y]=x;//    }//}stack<int>s;int dfs(int u,int fa){    pre[u]=low[u]=++dfs_clock;    s.push(u);    for(int i=p[u]; i+1; i=e[i].next)    {        int v=e[i].en;        if(!pre[v])        {            low[v]=dfs(v,u);            low[u]=min(low[u],low[v]);            if(low[v]>pre[u])            {//                e[i].fg=1;//                e[i^1].fg=1;                cnt++;            }//            else//            {//                Union(u,v);//            }        }        else if(pre[v]<pre[u]&&v!=fa)        {            low[u]=min(low[u],pre[v]);        }    }    if(low[u]==pre[u])    {       scc_cnt++;        while(1)        {           int x=s.top();            s.pop();            scc[x]=scc_cnt;            if(u==x)                break;       }    }    return low[u];}void find_scc(int n){    dfs_clock=cnt=scc_cnt=0;    memset(pre,0,sizeof(pre));    for(int i=0;i<=n;i++)        fa[i]=i;    dfs(1,-1);}int dfs1(int st,int fa,int tem){    if(ans<tem)    {        ans=tem;        root=st;    }    for(int i=p1[st]; i+1; i=e1[i].next)    {        int en=e1[i].en;        if(en==fa)continue;        dfs1(en,st,tem+1);    }    return root;}int main(){    int T;    scanf("%d",&T);    while(T--)    {        int n,m;        init();        init1();        scanf("%d%d",&n,&m);        for(int i=1; i<=m; i++)        {            int a,b;            scanf("%d%d",&a,&b);            add(a,b);            add(b,a);        }        find_scc(n);        if(cnt==0)        {            printf("0\n");            continue;        }        //int tot=num;        int xx;//        for(int i=0;i<tot;i++)//        {//            if(e[i].fg)//            {//                int u=Find(e[i].st);//                int v=Find(e[i].en);//                add1(u,v);//                xx=u;//            }//        }       for(int i=1; i<=n; i++)        {           for(int j=p[i]; j+1; j=e[j].next)           {               int en=e[j].en;               if(scc[i]!=scc[en])               {                   add1(scc[i],scc[en]);                   //add1(scc[en],scc[i]);               }            }        }        ans=0;        int x=dfs1(1,-1,0);        ans=0;        dfs1(x,-1,0);        printf("%d\n",cnt-ans);    }    return 0;}

0 0
原创粉丝点击