码迷,mamicode.com
首页 > 其他好文 > 详细

CodeForces Gym 100228 Graph of Inversions

时间:2018-10-05 16:03:16      阅读:127      评论:0      收藏:0      [点我收藏+]

标签:math   div   假设   sdi   pac   family   逆序   mil   name   

题目大意

对于一个长为$N$的序列$A$,定义它所对应的逆序图:

有$N$个点组成,标号为$1...N$的无向图,对于每一组$i,j(i<j)$若存在$A_i>A_j$则在新图中就存在一条$(A_i,A_j)$的无向边。

现在给定一个$N(N\leq 1000)$个点的图,保证它是某个序列对应的逆序图,求它有多少个点集$S$,满足$\forall x\in S,y\in S$不存在边$(x,y)$,$\forall x\notin S$至少存在一条边$(x,y)$使得$y\in S$。即求图独立覆盖集的数量。

 

 

题解

不难发现这个序列可以的转化为一个排列。

我们可以用拓扑排序整理每对数的大小关系,从而在序列上考虑这个问题。

对于第一个条件,即点集内两两没有连边,就是满足在序列上点集对应的位置恰好形成一个上升的子序列。

对于第二个条件,满足对于$\forall x\notin S$一定至少存在一个$y\in S$使得$A_x<A_y,x>y$或$A_y<A_x,x<y$。

假设$x\notin S,y\in S$,由于$\{A_y\}$为上升子序列,和$A_x$组成逆序对的是左侧最大的$A_x$和右侧最小的$A_x$,那么就是$A_y<A_x(x=max\{x\in S,x<y\})$或$A_y>A_x(x=\min\{x\in S,x>y\})$,即对于$i,j\in S,A_i$不存在$k$使得$i<k<j,A_i<A_k<A_j,k\notin S$这样就很显然了,直接$Dp$,设$F_i$表示最后一个是$i$前$i$个合法的方案数。

暴力转移即可。复杂度$O(n^2)$。

 

#include<algorithm>
#include<iostream>
#include<cstring>
#include<cstdio>
#include<cmath>
#define LL long long
#define M 1020
using namespace std;
LL read(){
	LL nm=0,fh=1; char cw=getchar();
	for(;!isdigit(cw);cw=getchar()) if(cw==‘-‘) fh=-fh;
	for(;isdigit(cw);cw=getchar()) nm=nm*10+(cw-‘0‘);
	return nm*fh;
}
LL n,m,fs[M],nt[M*M],to[M*M],tmp,ind[M],p[M],cnt,tot,q[M],hd,tl;
LL mp[M][M],F[M],G[M],ans;
void link(LL x,LL y){nt[tmp]=fs[x],fs[x]=tmp,to[tmp++]=y,ind[y]++;}
int main(){
	n=read(),m=read(),memset(fs,-1,sizeof(fs));
	while(m--) mp[read()+1][read()+1]=1;
	for(LL i=1;i<=n;i++){
		for(LL j=i+1;j<=n;j++)	if(mp[i][j]||mp[j][i]) link(j,i);else link(i,j);
	}
	for(LL i=1;i<=n;i++) if(!ind[i]) q[tl++]=i;
	while(hd<tl){
		LL x=q[hd++]; p[x]=++cnt;
		for(LL i=fs[x];i!=-1;i=nt[i]) if(!(--ind[to[i]])) q[tl++]=to[i];
	}
	F[0]=1;
	for(LL i=0;i<n;i++){
		LL minn=n+2;
		for(LL j=i+1;j<=n;j++){
			if(p[j]>minn||p[j]<p[i]) continue;
			F[j]+=F[i],minn=p[j];
		}
	}
	for(LL i=n,maxn=0;i;i--) if(p[i]>maxn) ans+=F[i],maxn=p[i];
	printf("%lld\n",ans);
	return 0;
}

 

CodeForces Gym 100228 Graph of Inversions

标签:math   div   假设   sdi   pac   family   逆序   mil   name   

原文地址:https://www.cnblogs.com/OYJason/p/9744776.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!