• WHYZOJ-#64 上白泽慧音(tarjan求强连通分量)


    【题目描述】:

    在幻想乡,上白泽慧音是以知识渊博闻名的老师。春雪异变导致人间之里的很多道路都被大雪堵塞,使有的学生不能顺利地到达慧音所在的村庄。因此慧音决定换一个能够聚集最多人数的村庄作为新的教学地点。

    人间之里由N个村庄(编号为1..N)和M条道路组成,道路分为两种一种为单向通行的,一种为双向通行的,分别用1和2来标记。

    如果存在由村庄A到达村庄B的通路,那么我们认为可以从村庄A到达村庄B,记为(A,B)。当(A,B)和(B,A)同时满足时,我们认为A,B是绝对连通的,记为。绝对连通区域是指一个村庄的集合,在这个集合中任意两个村庄X,Y都满足。

    现在你的任务是,找出最大的绝对连通区域,并将这个绝对连通区域的村庄按编号依次输出。若存在两个最大的,输出字典序最小的,比如当存在1,3,4和2,5,6这两个最大连通区域时,输出的是1,3,4。

    【输入描述】:

    第1行:两个正整数N,M

    第2..M+1行:每行三个正整数a,b,t, t = 1表示存在从村庄a到b的单向道路,t = 2表示村庄a,b之间存在双向通行的道路。保证每条道路只出现一次。

    【输出描述】:

    第1行: 1个整数,表示最大的绝对连通区域包含的村庄个数。

    第2行:若干个整数,依次输出最大的绝对连通区域所包含的村庄编号。

    【样例输入】:

    5 5
    1 2 1
    1 3 2
    2 4 2
    5 1 2
    3 5 1

    【样例输出】:

    3
    1 3 5

    【时间限制、数据范围及描述】:

    时间:1s 空间:128M

    对于60%的数据:N <= 200且M <= 10,000

    对于100%的数据:N <= 5,000且M <= 50,000

    肫帮我发现了我写的tarjan一直存在的bug(最开始的好像没有,后来由于POJ的辣鸡数据,好好的板子就被我打歪了还不自知),第一个判断下一个节点是否访问的时候同时要判断是否在栈中

     1 #include <cstdio>
     2 #include <cmath>
     3 #include <cstring>
     4 #include <cstdlib>
     5 #include <queue>
     6 #include <stack>
     7 #include <vector>
     8 #include <iostream>
     9 #include "algorithm"
    10 #define mem(a,b) memset(a,b,sizeof(a))
    11 using namespace std;
    12 typedef long long LL;
    13 const int MAX1=5005;
    14 const int MAX2=100005;
    15 int n,m;
    16 int head[MAX1],adj[MAX2],next[MAX2];
    17 int tot,tx;
    18 int low[MAX1],dfn[MAX1],sta[MAX1];
    19 bool t[MAX1],tt[MAX1];
    20 int ans[MAX1];
    21 inline int read(){
    22     int x=1,an=0;char c=getchar();
    23     while (c<'0' || c>'9'){if (c=='-') x=-1;c=getchar();}
    24     while (c>='0' && c<='9'){an=an*10+c-'0';c=getchar();}
    25     return x*an;
    26 }
    27 void addedge(int u,int v){
    28     tot++;
    29     adj[tot]=v;
    30     next[tot]=head[u];
    31     head[u]=tot;
    32 }
    33 void init(){
    34     int i,j;
    35     n=read();m=read();
    36     int x,y,z;
    37     ans[0]=sta[0]=tot=tx=0;
    38     mem(head,0),mem(t,false),mem(tt,false);
    39     for (i=1;i<=m;i++){
    40         x=read();y=read();z=read();
    41         if (z==1) addedge(x,y);
    42         if (z==2) addedge(x,y),addedge(y,x);
    43     }
    44 }
    45 void tarjan(int x){
    46     sta[++sta[0]]=x;
    47     dfn[x]=low[x]=++tx;
    48     tt[x]=t[x]=true;
    49     int i,j;
    50     for (i=head[x];i;i=next[i]){
    51         if (t[adj[i]] && tt[adj[i]])
    52             low[x]=min(low[x],dfn[adj[i]]);
    53         else{
    54             tarjan(adj[i]);
    55             low[x]=min(low[x],low[adj[i]]);
    56         }
    57     }
    58     if (low[x]>=dfn[x]){
    59         int zt[MAX1];
    60         zt[0]=0;
    61         do{
    62             tt[sta[sta[0]]]=false;
    63             zt[++zt[0]]=sta[sta[0]];
    64         }while (sta[sta[0]--]!=x);
    65         if (zt[0]>ans[0])
    66             for (i=0;i<=zt[0];i++) ans[i]=zt[i];
    67         if (zt[0]==ans[0]){
    68             bool flag=true;
    69             sort(zt+1,zt+zt[0]+1);
    70             for (i=1;i<=zt[0];i++){
    71                 if (zt[i]>ans[i]){
    72                     flag=false;
    73                     break;
    74                 }
    75             }
    76             if (flag)
    77                 for (i=0;i<=zt[0];i++) ans[i]=zt[i];
    78         }
    79     }
    80 }
    81 int main(){
    82     freopen ("classroom.in","r",stdin);
    83     freopen ("classroom.out","w",stdout);
    84     init();int i,j;
    85     for (i=1;i<=n;i++){
    86         if (!t[i])
    87             tarjan(i);
    88     }
    89     sort(ans+1,ans+ans[0]+1);
    90     printf("%d
    ",ans[0]);
    91     for (i=1;i<=ans[0];i++)
    92         printf("%d ",ans[i]);
    93     return 0;
    94 }
    未来是什么样,未来会发生什么,谁也不知道。 但是我知道, 起码从今天开始努力, 肯定比从明天开始努力, 要快一天实现梦想。 千里之行,始于足下! ——《那年那兔那些事儿》
  • 相关阅读:
    C# 依据鼠标坐标取网页内成员坐标.ie
    C# WebBrowser获取指定字符串的坐标
    C#获取网页中某个元素的位置,并模拟点击
    qq空间认证教程:借助企鹅媒体平台认证QQ公众空间
    QQ空间认证之数据篇
    QQ空间运营 怎么做一个QQ人气号?
    QQ空间|qq人气号怎么赚钱?
    QQ好友的价值玩法 及如何搞到几万好友?
    新媒体运营之如何月涨十万粉
    社群经济:如何利用社群做营销?
  • 原文地址:https://www.cnblogs.com/keximeiruguo/p/7324797.html
Copyright © 2020-2023  润新知