[Ybt Gold Navigation 3-6-2] [luogu UVA11294] [POJ 3648] Wedding / Wedding

Wedding

Topic link: ybt gold medal navigation 3-6-2 / luogu UVA11294 / POJ 3648

General idea

There are a bunch of couples, and then there are two sides, the same couple cannot be on the same side.
At the same time, some conditions are given, that is, no two people can be on the left at the same time.

Ask you if it is true, and if so, output one of the legal solutions.

Ideas

First of all, when you see the topic, you will naturally think of using 2-set to do it.

Then you consider building sides. For each pair, there is a male next to the groom and a female next to the groom.
Then if there is a conflict, connect to each other's other half.

Then there is a key point here is that the bride has to connect one side to the groom.
why?
Then you think, only the groom is restricted, and the bride is just sitting casually.
Then our 2-set must let the computer find the bridegroom's side.
How do you do it? We can connect the sides in this way, so that if the bride is chosen, the bridegroom must be chosen, and mistakes will occur. But if Xu Na is the bridegroom, there will be no pot.

Then let's see how to find the answer.
The answer for 2-set is to use the topological order and then to reverse the topological order, because if you press the inverse, there will be no conflicts, and the ones that don't need the inversion may conflict with the previously arranged ones.
Then you will find that the reverse topological order is actually the order of your abbreviated points, so you don't need to run again to find it.

Then how do you look over there in reverse topological order?
Because you chose the bridegroom for 2-set, and the answer is for the bride, we just need to reverse it when the time comes.
And now it's the bridegroom's side.
So if for a certain pair, then its two points will each have a reverse topological order. Then you must deal with the pre-reverse topological order first, that is, the post-topological order, then choose the one corresponding to this point.
(Remember to reverse this question!!!)

Then it's ok.

Code

#include<queue>
#include<cstdio>
#include<cstring>
#include<iostream>

using namespace std;

struct node {
    
    
	int to, nxt;
}e[500010];
int n, m, x, y, le[5001], KK;
char cx, cy, answer[5001];
int dfn[5001], low[5001], tmp;
int sta[5001], in[5001], n_n;
bool cant;

void csh() {
    
    //初始化
	memset(e, 0, sizeof(e));
	memset(le, 0, sizeof(le));
	KK = 0;
	memset(dfn, 0, sizeof(dfn));
	memset(low, 0, sizeof(low));
	tmp = 0;
	memset(sta, 0, sizeof(sta));
	memset(in, 0, sizeof(in));
	n_n = 0;
	cant = 0;
}

void add(int x, int y) {
    
    
	e[++KK] = (node){
    
    y, le[x]}; le[x] = KK;
}

int another(int x) {
    
    
	if (x > n) return x - n;
	return x + n;
}

void tarjan(int now) {
    
    //Tarjan缩点
	dfn[now] = low[now] = ++tmp;
	sta[++sta[0]] = now;
	
	for (int i = le[now]; i; i = e[i].nxt)
		if (!dfn[e[i].to]) {
    
    
			tarjan(e[i].to);
			low[now] = min(low[now], low[e[i].to]);
		}
		else if (!in[e[i].to]) low[now] = min(low[now], low[e[i].to]);
	
	if (dfn[now] == low[now]) {
    
    
		in[now] = ++n_n;
		while (sta[sta[0]] != now) {
    
    
			in[sta[sta[0]]] = n_n;
			sta[0]--;
		}
		sta[0]--;
	}
	
	return ;
}

int main() {
    
    
	scanf("%d %d", &n, &m);
	while (n || m) {
    
    
		csh();
		
		for (int i = 1; i <= m; i++) {
    
    
			scanf("%d%c %d%c", &x, &cx, &y, &cy);
			x++;
			y++;
			if (cx == 'h') x += n;
			if (cy == 'h') y += n; 
			add(x, another(y));//建图
			add(y, another(x));
		}
		add(1, 1 + n);//让程序选新郎那边的,因为新娘那边没有限制
		
		for (int i = 1; i <= 2 * n; i++)
			if (!dfn[i]) tarjan(i);
		
		for (int i = 1; i <= n; i++)//2-sat 的判断矛盾
			if (in[i] == in[n + i]) {
    
    
				cant = 1;
				printf("bad luck\n");
				break;
			}
		if (cant) {
    
    
			scanf("%d %d", &n, &m);
			continue;
		}
		
		for (int i = 2; i <= n; i++) {
    
    
			printf("%d", i - 1);//根据拓扑排序
			if (in[i] > in[i + n]) printf("w");
				else printf("h");
			printf(" ");
		}
		printf("\n");
		
		scanf("%d %d", &n, &m);
	}
	
	return 0;
}

Guess you like

Origin blog.csdn.net/weixin_43346722/article/details/113841157