2018QBXT刷题游记(6)

【2018QBXT刷题游记】

Day1 TEST2

T3 network

在计算机科学中,经常要通过分析变量之间的相关性来简化计算过程。变量
间的相关性可以用有向图 G=V,EG=( V,E)来表示,图中的点表示变量,边表示变量间
的关系。这里 GG 满足: GG 中的所有边都从编号小的点指向编号大的点。
从图中选出一个点集 TVT⊆V,如果 TT 中的任意两个点之间都有边(方向是编
号小的点指向编号大的点),则称 TT 为团。特别地,空集也认为是一个团。
如果存在一个点,与 TT 中的任意一个点之间都有边( 方向是编号小的点指
向编号大的点),那么称 T 为可扩团。
如果一个团 SS 不是可扩团,那么称它为极大团。
给出 GG,求 GG 有多少个不同的极大团。
这里 GG 满足一个性质:对于 GG 中任意一个点 ii, 用 H[i]H[i]表示编号比 i 小的点
中所有与 i 有边相连的点的集合,那么 H[i]H[i]是一个团。

【分析】这题好水啊……orz

根据提供的性质,只需要按照从大到小的顺序判断每一个点i

若与它相连的最大点j的入度比当前点小

那么以j为最大点的团一定是可扩团,i就是可扩点(还可能有更多)

注意重边的判断。

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
char c;int n,m,cnt,ans;int read(){c=getchar();int f=1,s=0;
while(c<'0'||c>'9')if(c=='-')f=-1,c=getchar();
while(c>='0'&&c<='9')s=s*10+c-'0',c=getchar();return f*s;}
struct Edge{
	int a,b;
}E[1000007];
int tot[1000007],last[1000007];bool qwq[1000007];
bool cmp(Edge x,Edge y){
	if(x.a!=y.a)return (x.a<y.a);
	else return (x.b<y.b);
}
int main(){
	freopen("network.in","r",stdin);
	freopen("network.out","w",stdout);
	n=read();m=read();
	for(int i=1;i<=m;i++){
		E[i].a=read();E[i].b=read();
	}cnt=0;
	sort(E+1,E+1+m,cmp);
	for(int i=1;i<=m;i++){
		cnt++;
		E[cnt]=E[i];
		while(i<m && E[i].a==E[i+1].a &&E[i].b==E[i+1].b)i++;
	}m=cnt;
	for(int i=1;i<=m;i++){
		tot[E[i].b]++;
		last[E[i].b]=max(E[i].a,last[E[i].b]);
	}ans=0;
	for(int i=n;i>=1;i--){
		if(last[i] && tot[i]>tot[last[i]])qwq[last[i]]=1;
		if(!qwq[i])ans++;
	}	
	printf("%d
",ans);
	return 0;
}
原文地址:https://www.cnblogs.com/erutsiom/p/9905139.html