bzoj2788 festival 差分约束
Posted Loser Of Life
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了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\n",ans); 100 } 101 int sb=haha(); 102 int main(){;}
以上是关于bzoj2788 festival 差分约束的主要内容,如果未能解决你的问题,请参考以下文章