• POJ1094 字母排序(拓扑排序)


    该题题意明确,就是给定一组字母的大小关系判断他们是否能组成唯一的拓扑序列。是典型的拓扑排序,但输出格式上确有三种形式:

       1.该字母序列有序,并依次输出;

       2.该序列不能判断是否有序;

       3.该序列字母次序之间有矛盾,即有环存在。

         而这三种形式的判断是有顺序的:先判断是否有环(3),再判断是否有序(1),最后才能判断是否能得出结果(2)。注意:对于(2)必须遍历完整个图,而(1)和(3)一旦得出结果,对后面的输入就不用做处理了。

     1 #include<iostream>
     2 #include<cstdio>
     3 #include<cstring>
     4 #include<vector>
     5 #include<algorithm>
     6 
     7 using namespace std;
     8 
     9 const int N=5005;
    10 vector<int>g[N];
    11 int dfn[N],low[N],dg[N],tim;
    12 bool vis[N],map[N][N];
    13 int n,r;
    14 
    15 void tarjan(int u,int fa)
    16 {
    17     dfn[u]=low[u]=++tim;
    18     vis[u]=1;
    19     for (int i=0;i<g[u].size();i++)
    20     {
    21         int v=g[u][i]; 
    22         if (v==fa) continue;
    23         if (!dfn[v])
    24         {
    25             tarjan(v, u); 
    26             low[u]=min(low[u],low[v]);
    27         }
    28         else if (vis[v]) low[u]=min(low[u],dfn[v]); 
    29     }
    30 }
    31 void init()
    32 {
    33     memset(dfn,0,sizeof(dfn)); 
    34     memset(low,0,sizeof(low)); 
    35     memset(vis,0,sizeof(vis)); 
    36     tim=0;
    37     tarjan(1,-1);
    38 }
    39 int main()
    40 {
    41     while (~scanf("%d%d",&n,&r))
    42     {
    43         for (int i=1;i<=n;i++) 
    44             g[i].clear();
    45         memset(map,0,sizeof(map));
    46         int u,v;
    47         for (int i=0;i<r;i++)
    48         {
    49             scanf("%d%d",&u,&v); 
    50             if (!map[u][v])
    51             {
    52                 g[u].push_back(v);
    53                 g[v].push_back(u);
    54                 map[u][v]=map[v][u]=1;
    55             }
    56         }
    57 
    58         init();
    59         memset(dg,0,sizeof(dg));
    60         
    61         for (int u=1;u<=n;u++)
    62             for (int i=0;i<g[u].size();i++)
    63             {
    64                 int v=g[u][i]; 
    65                 if (low[u]!=low[v]) dg[low[u]]++;  
    66             }
    67 
    68         int cnt=0;
    69         for (int i=1;i<=n;i++)
    70             if (dg[i]==1) cnt++;
    71         printf("%d
    ",(cnt+1)/2);
    72     }
    73 }
  • 相关阅读:
    再谈ORACLE CPROCD进程
    fopen()函数
    Java抓取网页数据(原网页+Javascript返回数据)
    Vmware ESX 5.0 安装与部署
    PostgreSQL服务端监听设置及client连接方法
    方向梯度直方图(HOG)和颜色直方图的一些比較
    Vim简明教程【CoolShell】
    FileSystemWatcher使用方法具体解释
    几种常见模式识别算法整理和总结
    ThreadPool.QueueUserWorkItem的性能问题
  • 原文地址:https://www.cnblogs.com/fengzhiyuan/p/7747711.html
Copyright © 2020-2023  润新知