• Vijos 桐桐的糖果计划 (tarjan求桥+双连通分量)


    背景

    桐桐是一个快乐的小朋友,他生活中有许多许多好玩的事,让我们一起来看看吧……

    描述

    桐桐很喜欢吃棒棒糖。他家处在一大堆糖果店的附近。

    但是,他们家的区域经常出现塞车、塞人等情况,这导致他不得不等到塞的车或人走光了他才能去买到他最爱吃的棒棒糖品种。于是,他去找市长帮他修路,使得每两个糖果店之间至少有两条完全不同的路。可是市长经费有限,于是让桐桐找出哪些路被塞住后会使某些糖果店与糖果店间无法到达及最少的修路条数。你能帮助他吃到他最喜爱的糖果吗?
    注:
    1->3->2 和 1->3->4->2 为不完全不同的路,即不符合题意的路。

    1->3->4->2 和 1->5->2 为完全不同的路,即符合题意的路。

    格式

    输入格式

    输入第一行是两个数n,m(n<=5000,m<=10000)
    接下来的m行,每行两个数i,j,表示i,j间有一条边连接。

    输出格式

    输出有两行。第一行为塞住后就不可以到达某些糖果店的道路条数,第二行为最少的修路条数。

    样例1

    样例输入1

    7 7
    1 2
    2 3
    3 4
    2 5
    4 5
    5 6
    5 7
    

    样例输出1

    3
    2
    

    限制

    提示


    1 2 3
    +---+---+ 
    | |
    | |
    6 +---+---+ 4
    / 5


    7 +

    上图是样例所表示的一个图。

    下图是改变后的图,其中虚线表示应连接的边。


    1 2 3
    +---+---+
    : | |
    : | |
    6 +---+---+ 4
    / 5 :
    / :
    / :
    7 + - - - -

     1 /* 
     2     tarjan求桥+双连通分量
     3     注意判重边
     4 */
     5 #include<cstdio>
     6 #include<cstring>
     7 #include<iostream>
     8 #define MAXN 5010
     9 
    10 using namespace std;
    11 
    12 int n,m;
    13 
    14 struct node {
    15     int to;
    16     int next;
    17 };
    18 node e[MAXN*2];
    19 int head[MAXN],tot;
    20 
    21 int dfn[MAXN],low[MAXN],stack[MAXN],belong[MAXN],top,idex,cnt,ans;
    22 bool vis[MAXN];
    23 
    24 int in[MAXN];
    25 
    26 inline void read(int&x) {
    27     int f=1;x=0;char c=getchar();
    28     while(c>'9'||c<'0') {if(c=='-') f=-1;c=getchar();}
    29     while(c>='0'&&c<='9') {x=(x<<1)+(x<<3)+c-48;c=getchar();}
    30     x=x*f;
    31 }
    32 
    33 inline void add(int x,int y) {
    34     e[tot].to=y;
    35     e[tot].next=head[x];
    36     head[x]=tot++;
    37 }
    38 
    39 inline void tarjan(int u,int fa) {
    40     dfn[u]=low[u]=++idex;
    41     stack[++top]=u;
    42     vis[u]=true;
    43     for(int i=head[u];i!=-1;i=e[i].next) {
    44         if(i==(fa^1)) continue;//判重边
    45         int v=e[i].to;
    46         if(!dfn[v]) {
    47             tarjan(v,i);
    48             low[u]=min(low[u],low[v]);
    49             if(low[v]>dfn[u]) ans++;//求桥的数量
    50         }
    51         else if(vis[u]) low[u]=min(dfn[v],low[u]);
    52     }
    53     if(dfn[u]==low[u]) {
    54         cnt++;
    55         int t;
    56         do {
    57             t=stack[top--];
    58             belong[t]=cnt;
    59             vis[t]=false;
    60         }while(u!=t);
    61     }
    62     return;
    63 }
    64 
    65 int main() {
    66     int x,y;
    67     read(n);read(m);
    68     memset(head,-1,sizeof head);
    69     for(int i=1;i<=m;i++) {
    70         read(x);read(y);
    71         add(x,y);add(y,x);
    72     }
    73     for(int i=1;i<=n;i++)
    74       if(!dfn[i])
    75         tarjan(i,-1);
    76     printf("%d
    ",ans);
    77     for(int i=1;i<=n;i++)
    78       for(int j=head[i];j!=-1;j=e[j].next) {
    79             int v=e[j].to;
    80           if(belong[i]!=belong[v])
    81             in[belong[i]]++;
    82       }
    83     ans=0;
    84     for(int i=1;i<=n;i++)
    85       if(in[i]==1)
    86         ans++;
    87     printf("%d
    ",(ans+1)/2);
    88     return 0;
    89 }
    代码


    作者:乌鸦坐飞机
    出处:http://www.cnblogs.com/whistle13326/
    新的风暴已经出现 怎么能够停止不前 穿越时空 竭尽全力 我会来到你身边 微笑面对危险 梦想成真不会遥远 鼓起勇气 坚定向前 奇迹一定会出现

     
  • 相关阅读:
    readelf的使用,看函数地址
    Linux 打印堆栈和crash地址转换
    Android mk 添加打印信息
    Linux make file文件中常用的一些定义CPP CXX
    关于Android中RemoveView的错误理解
    Android悬浮窗注意事项
    在有EditText控件的AlertDialog对话框中自动弹出输入法
    联系旭日150安装CentOS5.X版本手记
    ListView配合CheckBox出现position位置错误的解决
    在Android中让Preference的宽度占满整个屏幕的宽度
  • 原文地址:https://www.cnblogs.com/whistle13326/p/6961350.html
Copyright © 2020-2023  润新知