zoukankan      html  css  js  c++  java
  • POJ2762(Going from u to v or from v to u?)

    题目链接

    题目大意,给一个有向图,求是否任意两点都单向联通。

    这题我用的是两次dfs求强连通图,将强连通分量缩成一个点,然后对缩点后的有向图进行拓扑排序,判断单项连通。因为一个小错误,WA了3次,第一次dfs时是求各点的后根遍历次序(时间戳),但是是以第cnt次访问的是第v个结点的形式来保存,这样可以很方便从访问次序找相应结点,便于第二次dfs。我在写的时候,不小心就写成了保存第v个结点的时间戳,自然就错了。

    View Code
      1 #include <stdio.h>
    2 #include <memory.h>
    3 #define CLR(a) memset(a,0,sizeof(a))
    4 #define N 1005
    5 #define M 6005
    6 struct node
    7 {
    8 int a,b;
    9 } edge[M];
    10 char g[N][N],vis[N];
    11 int n,m,ord[N],id[N],topord[N],cnt;
    12 void dfs(int u)
    13 {
    14 int v;
    15 vis[u]=1;
    16 for(v=1; v<=n; v++)
    17 {
    18 if(g[u][v]&&!vis[v])
    19 {
    20 dfs(v);
    21 }
    22 }
    23 ord[cnt++]=u;
    24 }
    25 void rdfs(int u)
    26 {
    27 int v;
    28 vis[u]=1;
    29 id[u]=cnt;
    30 for(v=1; v<=n; v++)
    31 {
    32 if(g[v][u]&&!vis[v])
    33 {
    34 rdfs(v);
    35 }
    36 }
    37 }
    38 void kosaraju()
    39 {
    40 int i,t,a,b;
    41 CLR(vis);
    42 for(i=1,cnt=1; i<=n; i++)
    43 {
    44 if(!vis[i]) dfs(i);
    45 }
    46 CLR(vis);
    47 for(t=n,cnt=0; t>0; t--)
    48 {
    49 i=ord[t];
    50 if(!vis[i])
    51 {
    52 cnt++;
    53 rdfs(i);
    54 }
    55 }
    56 CLR(g);
    57 for(i=0; i<m; i++)
    58 {
    59 a=id[edge[i].a],b=id[edge[i].b];
    60 if(a==b) continue;
    61 g[a][b]=1;
    62 }
    63 }
    64 void topsort()
    65 {
    66 int d[N],i,j,k;
    67 for(i=1; i<=cnt; i++)
    68 {
    69 d[i]=0;
    70 for(j=1; j<=cnt; j++)
    71 {
    72 if(i==j) continue;
    73 d[i]+=g[j][i];
    74 }
    75 }
    76 for(k=0; k<cnt; k++)
    77 {
    78 for(i=1; d[i]&&i<=n; i++);
    79 d[i]=-1;
    80 for(j=1; j<=cnt; j++) d[j]-=g[i][j];
    81 topord[k]=i;
    82 }
    83 }
    84 void judge()
    85 {
    86 int i,flag=1;
    87 for(i=0; i<cnt-1; i++)
    88 {
    89 if(!g[topord[i]][topord[i+1]])
    90 {
    91 flag=0;
    92 break;
    93 }
    94 }
    95 if(flag) printf("Yes\n");
    96 else printf("No\n");
    97 }
    98 int main()
    99 {
    100 int t,i,a,b;
    101 scanf("%d",&t);
    102 while(t--)
    103 {
    104 scanf("%d%d",&n,&m);
    105 for(i=0; i<m; i++)
    106 {
    107 scanf("%d%d",&a,&b);
    108 if(a==b) continue;
    109 g[a][b]=1;
    110 edge[i].a=a,edge[i].b=b;
    111 }
    112 kosaraju();
    113 topsort();
    114 judge();
    115 CLR(g);
    116 }
    117 return 0;
    118 }
  • 相关阅读:
    02.创建型————工厂方法模式
    01.创建型————简单工厂模式
    HBase JavaAPI操作示例
    MongoDB
    大数据第三天
    Zookeeper操作
    MR操作
    HDFS操作
    【GISER&&Painter】svg的那些事
    读法克鸡丝博文《技术,产品,团队》有感
  • 原文地址:https://www.cnblogs.com/algorithms/p/2427746.html
Copyright © 2011-2022 走看看