zoukankan      html  css  js  c++  java
  • BZOJ3355

    3355: [Usaco2004 Jan]有序奶牛

    Time Limit: 10 Sec  Memory Limit: 128 MB
    Submit: 37  Solved: 19
    [Submit][Status][Discuss]

    Description

        约翰的N(1≤N≤1500)头牛排成一行挤奶时,有确定的顺序.牛被编成连续的号码1..N,他拥有L条关于奶牛顺序的信息,所有的信息都写成“A在B的前面”这样的形式,而且他知道最后一条是多余的.他觉得,有些冗余信息可以由其他信息推出,可以对这些信息进行精减.请帮助约翰删除尽可能多的冗余信息,但要保证能推出原有的顺序.可以保证的是,答案唯一,且最初的信息没有矛盾,如A在B前面,B在A前面.

    Input

     
        第1行:两个整数N和L.
        第2到L+1行:每行两个整数X和Y(1≤X,y≤N),表示X在Y前.无重复.

    Output

     
        第1行:整数U.
        第2到U+I行:输出精减后的信息,每行2个数字,按第1列数字排序.

    Sample Input

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

    Sample Output

    4
    2 1
    3 5
    4 2
    5 2

    HINT

    3在1前,4在1前可推.输出的每一行,不能被其他推出.

    分析:对于一条边x->y,若去掉之后x不能到达y,那么它是必需的。我们首先需要求出拓扑序列,然后我们按照拓扑序列反向加边,这样的目的就是为了在已知顺序的情况下维护哪些边可以互相到达,然后用一个bieset去判断一下哪些边是必须的。感谢claris和付大神对我的帮助

     1 #include "iostream"
     2 #include "cstdio"
     3 #include "cstring"
     4 #include "bitset"
     5 #include "algorithm"
     6 using namespace std;
     7 const int maxn=1500+10;
     8 const int maxm=15000+10;
     9 int n,m,ed,ed2;
    10 int ind[maxn]; //入度
    11 int adj[maxm]; //栈顶边对应的顶点
    12 int next1[maxm]; //上一条边的编号
    13 int tail[maxm]; //栈顶边的编号
    14 int vis[maxn];  //存储拓扑排序序列
    15 bitset<maxn>f[maxn];
    16 void add(int x,int y){
    17     ind[y]++;
    18     adj[++ed]=y;
    19     next1[ed]=tail[x];
    20     tail[x]=ed;
    21 }
    22 int adj2[maxm];
    23 int next2[maxm];
    24 int tail2[maxm];
    25 void add2(int x,int y){
    26     adj2[++ed2]=y;
    27     next2[ed2]=tail2[x];
    28     tail2[x]=ed2;
    29 }
    30 typedef pair<int,int> P;
    31 P p[maxm];
    32 int main()
    33 {
    34     //freopen("a.txt", "r", stdin);  
    35     //freopen("b.txt", "w", stdout);
    36     scanf("%d%d",&n,&m);
    37     for(int i=1;i<=n;i++)  f[i][i]=1;
    38     ed=0;
    39     while(m--){    //数组式邻接表建图
    40         int x,y;
    41         scanf("%d%d",&x,&y);
    42         add(x,y);
    43     }
    44 
    45     //构造拓扑排序序列
    46     int cnt=0;
    47     for(int i=1;i<=n;i++)
    48         if(!(ind[i]))
    49             vis[++cnt]=i;
    50 
    51     int h=1;
    52     ed2=0;
    53     while(h<=cnt){
    54         int a;
    55         for(int i=tail[a=vis[h++]];i;add2(adj[i],a),i=next1[i])
    56             if(!(--ind[adj[i]]))
    57                 vis[++cnt]=adj[i];
    58     }
    59 
    60     int ans=0;
    61     for(int i=1;i<=n;i++){
    62         int a;
    63         for(int j=tail2[a=vis[i]];j;f[a]|=f[adj2[j]],j=next2[j])
    64             if(!f[a][adj2[j]])
    65                 p[++ans]=P(adj2[j],a);
    66     }
    67     sort(p+1,p+1+ans);
    68     printf("%d
    ",ans);
    69     for(int i=1;i<=ans;i++)
    70         printf("%d %d
    ",p[i].first,p[i].second);
    71     return 0;
    72 }
    View Code
  • 相关阅读:
    js获取长度,根据编码获取长度
    springcloud(七,多个服务消费者配置,以及zuul网关案例)
    springcloud(六,多个服务提供者)
    springcloud(五,多个服务注册中心eureka)
    jquery根据选择器进行页面赋值,封装赋值方法
    让页面元素无法选中,不能全选
    取消绑定事件
    js设置元素指定时间隐藏
    js手动抛出异常
    php 之 数据访问 查询关键字 (0506)
  • 原文地址:https://www.cnblogs.com/wolf940509/p/6679379.html
Copyright © 2011-2022 走看看