[J]computer network tarjan边双联通分量+树的直径

https://odzkskevi.qnssl.com/b660f16d70db1969261cd8b11235ec99?v=1537580031

【2012-2013 ACM Central Region of Russia Quarterfinal Programming Contest】【J】computer network

题意:

n个点,m条边,构成一个无向图,现在让你再任意连接两个点,使得整个图的割边最少。

1 ≤ n ≤ 10 000; 1≤ m ≤ 100 000; 1 ≤ xi, yi ≤ n; xi ≠ yi.

题解:
tarjan求边双联通分量,缩点,形成一棵树,求树的直径,然后把直径的两个端点连起来就好。

  1 #include<cstdio>
  2 #include<cstdlib>
  3 #include<cstring>
  4 #include<algorithm>
  5 #include<iostream>
  6 using namespace std;
  7 
  8 // const int maxN=100;
  9 // int a[maxN+10];
 10 const int N=10010,M=100010;
 11 int dfn[N],low[N],first[N],bfir[N],v[N],c[N],s[N],id[2];
 12 int n,m,al,bl,sl,num,mx,cnt;
 13 struct node{
 14     int x,y,next,tmp;
 15 }a[2*M],b[2*M];
 16 
 17 int minn(int x,int y){return x<y ? x:y;}
 18 
 19 void ins(int x,int y)
 20 {
 21     al++;a[al].tmp=0;
 22     a[al].x=x;a[al].y=y;a[al].next=first[x];first[x]=al;
 23 }
 24 
 25 void anins(int x,int y)
 26 {
 27     bl++;b[bl].tmp=0;
 28     b[bl].x=x;b[bl].y=y;b[bl].next=bfir[x];bfir[x]=bl;
 29 }
 30 
 31 void tarjan(int x,int fa)
 32 {
 33     dfn[x]=low[x]=++num;
 34     s[++sl]=x;
 35     for(int i=first[x];i;i=a[i].next)
 36     {
 37         if(a[i].tmp) continue;
 38         a[i%2==0 ? i-1:i+1].tmp=1;
 39         int y=a[i].y;
 40         if(!dfn[y])
 41         {
 42             tarjan(y,x);
 43             low[x]=minn(low[x],low[y]);
 44         }
 45         else if(!c[y]) low[x]=minn(low[x],dfn[y]);
 46     }
 47     if(dfn[x]==low[x])
 48     {
 49         cnt++;
 50         int z=0;
 51         while(1)
 52         {
 53             z=s[sl];sl--;
 54             v[z]=0;
 55             c[z]=cnt;
 56             if(z==x) break;
 57         }
 58     }
 59 }
 60 
 61 void dfs(int x,int fa,int dep,int tmp)
 62 {
 63     if(dep>mx) mx=dep,id[tmp]=x;
 64     for(int i=bfir[x];i;i=b[i].next)
 65     {
 66         int y=b[i].y;
 67         if(y==fa) continue;
 68         dfs(y,x,dep+1,tmp);
 69     }
 70 }
 71 
 72 int main()
 73 {
 74     freopen("input.txt","r",stdin);
 75     freopen("output.txt","w",stdout);
 76     scanf("%d%d",&n,&m);
 77     al=0;sl=0;bl=0;num=0;cnt=0;
 78     memset(bfir,0,sizeof(bfir));
 79     memset(first,0,sizeof(first));
 80     memset(dfn,0,sizeof(dfn));
 81     memset(low,0,sizeof(low));
 82     memset(c,0,sizeof(c));
 83     for(int i=1;i<=m;i++)
 84     {
 85         int x,y;
 86         scanf("%d%d",&x,&y);
 87         ins(x,y);ins(y,x);
 88     }
 89     for(int i=1;i<=n;i++)
 90     {
 91         if(!dfn[i]) num=0,tarjan(i,0);
 92     }
 93     // for(int i=1;i<=n;i++) printf("c [ %d ] = %d\n",i,c[i]);
 94     for(int i=1;i<=2*m;i++)
 95     {
 96         int x=a[i].x,y=a[i].y;
 97         if(c[y]==c[x]) continue;
 98         anins(c[x],c[y]);
 99         // printf("%d -- > %d\n",c[x],c[y]);
100     }
101     mx=0,dfs(1,0,0,0);
102     mx=0,dfs(id[0],0,0,1);
103     for(int i=1;i<=n;i++)
104         if(c[i]==id[0]) {printf("%d ",i);break;}
105     for(int i=1;i<=n;i++)
106         if(c[i]==id[1]) {printf("%d\n",i);break;}
107     // printf("%d %d\n",id[0],id[1]);
108     return 0;
109 }

猜你喜欢

转载自www.cnblogs.com/KonjakJuruo/p/9697859.html