• [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
    ",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 }
  • 相关阅读:
    AGC/ARC
    日常训练
    SQL经典问题四表查询(教师,学生,成绩,课程表)---MySQL版
    15个最佳的 JavaScript 表单验证库
    推荐6个国内技术大牛博客,全栈工程师修行的秘籍!(建议收藏)
    java-linux安装和配置
    vue学习笔记
    JVM学习笔记
    SpringMVC学习笔记
    Mybatis学习笔记
  • 原文地址:https://www.cnblogs.com/KonjakJuruo/p/9697859.html
Copyright © 2020-2023  润新知