璟雯院

珺璟如晔,雯华若锦

用户工具

站点工具


icpc:problems:luogup3068
problems
名称Party Invitations S
题目编号P3068
题目链接luogu.com.cn/…
来源Luogu
算法分类拓扑排序
难易程度容易

Party Invitations S

想法

记录每个点拥有的朋友圈,记录每个朋友圈拥有的点。对朋友圈进行类似于拓扑排序的操作,当朋友圈中的还剩最后一个时,将所有与这个最后一个牛的朋友圈均加入队列,重新更新这些朋友圈。直到没有朋友圈能更新为止。

代码实现

#include<cstdio>
#include<cstring>
#include<queue>
using namespace std;
const int M = 250010;
const int N = 1e6+10;
struct node {
	int v, next;
};
node toCir[M];
node toPoint[M];
int headToCir[N], headToPoint[N], cntToCir, cntToPoint, size[M];
bool vis[M], ans[N];
void add_edge_Cir(int cow, int cir) {
	toCir[++cntToCir].v = cir;
	toCir[cntToCir].next = headToCir[cow];
	headToCir[cow] = cntToCir;
	return ;
}
void add_edge_Poi(int cow, int cir) {
	toPoint[++cntToPoint].v = cow;
	toPoint[cntToPoint].next = headToPoint[cir];
	headToPoint[cir] = cntToPoint;
	return ;
}
int main() {
	memset(headToCir, -1, sizeof(headToCir));
	memset(headToPoint, -1, sizeof(headToPoint));
	int n, g, cow;
	scanf("%d %d", &n, &g);
	for(int i=1; i<=g; i++) {
		scanf("%d", &size[i]);
		for(int j=1; j<=size[i]; j++) {
			scanf("%d", &cow);
			add_edge_Cir(cow, i);
			add_edge_Poi(cow, i);
		}
	}
	queue<int>qu;
	ans[1] = true;
	for(int i=headToCir[1]; ~i; i=toCir[i].next) {
		int cir = toCir[i].v;
		vis[cir] = true;
		qu.push(cir);
	}
	while(!qu.empty()) {
		int now = qu.front(); qu.pop();
		vis[now] = false;
		int cnt = 0, last = 0;
		for(int i=headToPoint[now]; ~i; i=toPoint[i].next) {
			int point = toPoint[i].v;
			if(ans[point])
				cnt++;
			else
				last = point;
		}
		if(cnt == size[now]-1) {
			ans[last] = true;
			for(int i=headToCir[last]; ~i; i=toCir[i].next) {
				int cir = toCir[i].v;
				if(vis[cir])continue;
				qu.push(cir);
				vis[cir] = true;
			}
		}
	}
	int ansCnt = 0;
	for(int i=1; i<=n; i++)
		if(ans[i])
			ansCnt++;
	printf("%d", ansCnt);
	return 0;
}
/app/www/public/data/pages/icpc/problems/luogup3068.txt · 最后更改: 2024/02/18 14:50 由 温婕莺