• bzoj2788 festival 差分约束


    填坑中……链接:http://www.lydsy.com/JudgeOnline/problem.php?id=2788

    题意:

    有$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}$大小的最大值。

    首先看情况我们也知道是差分约束……

    但是这个差分约束有些不一样在于这个东西会出环……所以我们要得出强连通分量……

    得出来之后对于每个$SCC$分别考虑就行了……

      1 #include<iostream>
      2 #include<cstdio>
      3 #include<algorithm>
      4 #include<cstring>
      5 using namespace std;
      6 const int maxn=605,maxm=200005;
      7 const int inf=0x3f3f3f3f;
      8 int n,m1,m2,cnt,tot,scnt;
      9 int head[maxn],MAP[maxn][maxn];
     10 int dfn[maxn],low[maxn],belong[maxn];
     11 struct node
     12 {
     13     int from,to,dis,next;
     14 }edge[maxm];
     15 void addedge(int u,int v,int w)
     16 {
     17     edge[++tot]=(node){u,v,w,head[u]};head[u]=tot;
     18 }
     19 #include<stack>
     20 stack<int>s;
     21 void tarjan(int root)
     22 {
     23     dfn[root]=low[root]=++cnt;s.push(root);
     24     for(int i=head[root];i;i=edge[i].next)
     25     {
     26         int v=edge[i].to;
     27         if(!dfn[v])
     28         {
     29             tarjan(v);
     30             low[root]=min(low[root],low[v]);
     31         }
     32         else if(!belong[v])low[root]=min(low[root],dfn[v]);
     33     }
     34     if(low[root]==dfn[root])
     35     {
     36         scnt++;int k;
     37         do
     38         {
     39             k=s.top();s.pop();
     40             belong[k]=scnt;
     41         }while(k!=root);
     42     }
     43 }
     44 int haha()
     45 {
     46     scanf("%d%d%d",&n,&m1,&m2);
     47     for(int i=1;i<=n;i++)
     48         for(int j=1;j<=n;j++)MAP[i][j]=-inf;
     49     for(int i=1;i<=n;i++)MAP[i][i]=0;
     50     for(int i=1;i<=m1;i++)
     51     {
     52         int x,y;scanf("%d%d",&x,&y);
     53         addedge(x,y,1),addedge(y,x,-1);
     54         MAP[x][y]=max(MAP[x][y],1);MAP[y][x]=max(MAP[y][x],-1);
     55     }
     56     for(int i=1;i<=m2;i++)
     57     {
     58         int x,y;scanf("%d%d",&x,&y);
     59         addedge(x,y,0);MAP[x][y]=max(MAP[x][y],0);
     60     }
     61     for(int i=1;i<=n;i++)
     62         if(!dfn[i])tarjan(i);
     63     int ans=0;
     64     for(int b=1;b<=scnt;b++)
     65     {
     66         int ret=0;
     67         for(int k=1;k<=n;k++)
     68         {
     69             if(belong[k]!=b)continue;
     70             for(int i=1;i<=n;i++)
     71             {
     72                 if(belong[i]!=b)continue;
     73                 if(MAP[i][k]==-inf)continue;
     74                 for(int j=1;j<=n;j++)
     75                 {
     76                     if(belong[j]!=b)continue;
     77                     if(MAP[k][j]==-inf)continue;
     78                     MAP[i][j]=max(MAP[i][j],MAP[i][k]+MAP[k][j]);
     79                 }
     80             }
     81         }
     82         for(int i=1;i<=n;i++)
     83         {
     84             if(belong[i]!=b)continue;
     85             for(int j=1;j<=n;j++)
     86             {
     87                 if(belong[j]!=b)continue;
     88                 ret=max(ret,abs(MAP[i][j]));
     89             }
     90         }
     91         ans+=ret+1;
     92     }
     93     for(int i=1;i<=n;i++)
     94         if(MAP[i][i])
     95         {
     96             puts("NIE");
     97             return 0;
     98         }
     99     printf("%d
    ",ans);
    100 }
    101 int sb=haha();
    102 int main(){;}
    bzoj2788
  • 相关阅读:
    2017.10.20
    2017.10.14
    2017.10.19
    2017.10.18
    2017.10.17
    软件工程个人作业02
    构建之法读后感03
    构建之法阅读笔记02
    二柱子问题(随机产生四则运算题目)
    课后作业2(构建之法阅读计划)
  • 原文地址:https://www.cnblogs.com/Loser-of-Life/p/7351585.html
Copyright © 2020-2023  润新知