zoukankan      html  css  js  c++  java
  • [BZOJ2788][Poi2012]Festival

    2788: [Poi2012]Festival

    Time Limit: 30 Sec  Memory Limit: 64 MB
    Submit: 187  Solved: 91
    [Submit][Status][Discuss]

    Description

     

     

    有n个正整数X1,X2,...,Xn,再给出m1+m2个限制条件,限制分为两类:

    1. 给出a,b (1<=a,b<=n),要求满足Xa + 1 = Xb

    2. 给出c,d (1<=c,d<=n),要求满足Xc <= Xd

    在满足所有限制的条件下,求集合{Xi}大小的最大值。

     

     

    Input

     


    第一行三个正整数n, m1, m2 (2<=n<=600, 1<=m1+m2<=100,000)。

    接下来m1行每行两个正整数a,b (1<=a,b<=n),表示第一类限制。

    接下来m2行每行两个正整数c,d (1<=c,d<=n),表示第二类限制。

     

     

     

    Output

    一个正整数,表示集合{Xi}大小的最大值。

     

     

    如果无解输出NIE。

     

    Sample Input

    4 2 2

    1 2

    3 4

    1 4

    3 1

    Sample Output

    3

    HINT

    |X3=1, X1=X4=2, X2=3


    这样答案为3。容易发现没有更大的方案。



    Source

    [Submit][Status][Discuss]


    此题显然是个差分约束系统,先建好图。

    如果两个点不是强连通的,显然这两个点不会互相影响。

    所以先tarjan缩点,如果不在一个强连通块里的不会有影响,所以只需要考虑同意连通块内的点。

    求元素不同的最大值等价于连通块内的最长路+1,由于数据范围较小,floyd即可。

    如果存在正环,则 无解。

     1 #include<cstdio>
     2 #include<algorithm>
     3 #define N 605
     4 #define M 500010
     5 using namespace std;
     6 int head[N],dfn[N],belong[N],low[N],scc;
     7 int map[N][N],q[N],top,tot,n,m1,m2,id,ans;
     8 bool vis[N];
     9 struct edge{int next,to;}e[M];
    10 #define add(u,v) e[++tot]=(edge){head[u],v},head[u]=tot
    11 void tarjan(int x)
    12 {
    13     low[x]=dfn[x]=++id;
    14     q[++top]=x;vis[x]=1;
    15     for(int i=head[x];i;i=e[i].next)
    16     if(!dfn[e[i].to])
    17     tarjan(e[i].to),low[x]=min(low[x],low[e[i].to]);
    18     else if(vis[e[i].to])
    19     low[x]=min(low[x],dfn[e[i].to]);
    20     int now=0;
    21     if(low[x]==dfn[x])
    22     {
    23         scc++;
    24         while(now!=x)
    25         {
    26             now=q[top--];
    27             belong[now]=scc;
    28             vis[now]=0;
    29         }
    30     }
    31 }
    32 int main()
    33 {
    34     scanf("%d%d%d",&n,&m1,&m2);
    35     for(int i=1;i<=n;i++)
    36     for(int j=1;j<=n;j++)
    37     if(i!=j)map[i][j]=-1e9;
    38     else map[i][j]=0;
    39     int x,y;
    40     while(m1--)
    41     {
    42         scanf("%d%d",&x,&y);
    43         add(x,y);
    44         add(y,x);
    45         map[x][y]=max(map[x][y],1);
    46         map[y][x]=max(map[y][x],-1);
    47     }
    48     while(m2--)
    49     {
    50         scanf("%d%d",&x,&y);
    51         add(x,y);
    52         map[x][y]=max(map[x][y],0);
    53     }
    54     for(int i=1;i<=n;i++)
    55     if(!dfn[i])tarjan(i);
    56     for(int p=1;p<=scc;p++)
    57     {
    58         for(int k=1;k<=n;k++)if(belong[k]==p)
    59         for(int i=1;i<=n;i++)if(belong[i]==p)
    60         if(map[i][k]!=-1e9)
    61         for(int j=1;j<=n;j++)if(belong[j]==p)
    62         if(map[k][j]!=-1e9)
    63         map[i][j]=max(map[i][j],map[i][k]+map[k][j]);
    64         int now=0;
    65         for(int i=1;i<=n;i++)if(belong[i]==p)
    66         for(int j=1;j<=n;j++)if(belong[j]==p)
    67         now=max(now,abs(map[i][j]));
    68         ans+=now+1;
    69     }
    70     for(int i=1;i<=n;i++)
    71     if(map[i][i]!=0)
    72     return puts("NIE"),0;
    73     printf("%d",ans);
    74 }
    View Code
    就让我永远不在这里写什么有意义的话--月下孤狼
  • 相关阅读:
    Pytorch tensor求和( tensor.sum())
    Pytorch torch.cat(inputs, dimension=0)
    README.md编写
    Numpy-np.random.normal()正态分布
    numpy数组的分割与合并
    使用Pandas读取CSV文件
    train loss与test loss结果分析/loss不下降
    Python-给数字/字符串前加0
    SVM简单上手示例
    迁移学习简介
  • 原文地址:https://www.cnblogs.com/xuruifan/p/5189175.html
Copyright © 2011-2022 走看看