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 ",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 ",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 ",i);break;} 107 // printf("%d %d ",id[0],id[1]); 108 return 0; 109 }