当前位置:网站首页>【luogu P8326】Fliper (Graph Theory) (Construction) (Eulerian Circuit)
【luogu P8326】Fliper (Graph Theory) (Construction) (Eulerian Circuit)
2022-07-31 16:40:00 【SSL_TJH】
Fliper
题目链接:luogu P8326
题目大意
平面上有 n 个挡板(Top left to bottom right and top right to bottom left),If the ball touches it will 90 change the trajectory.
Then you want to give each baffle a color,Makes a bounce sequence for each loop,The number of baffles that satisfy each color is the same and an even number.(If a baffle appears twice in the sequence it counts twice)
If the scheme output cannot be constructed -1.
思路
First consider finding the loop.
That is to split a baffle into two points(两面),Then, along with an edge of the same color, the color of this edge determines the color of the baffle.
Then you connect the two points of a face that bounce from one face back to one place,Then shrink this a bit.
That would make some big points(Represents a cyclic sequence),and some other points(not in a circular sequence),Then we connect it to one i n f \rm inf inf 点.
Then consider dyeing,You will find that you have to satisfy all the looping sequences,If brute force can solve the equation but the complexity is too large.
Consider finding some character,Then this is a graph, let's look for the properties of graph theory.
When we find a solution, let's see what happens,It is not difficult to think of the situation where the degree of each large point should be 8 8 8 的倍数.
Then there is a property in graph theory that there is always an even number of points with an odd degree.
Then we can get that i n f \rm inf inf The degree of the point must also be even.(If it is an odd number then only 1 1 1 个点,不是偶数个)
It's not hard to think of something called an Euler circuit.
Consider finding Euler circuits and then coloring them in black and white,Then we have two colors.
It is not difficult to come up with four approaches:Because after this the degree is 4 4 4 的倍数,So there is also an Euler circuit.(According to the above graph theory properties, there will also be i n f \rm inf inf The number of points is an even number)
Then we will run another Euler circuit for the two separated color maps,It's divided into four.
代码
#include<queue>
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
const int N = 5e5 + 1000;
/* op=0: / , op=1: \ */
/* i / n+i i \ n+i */
struct node {
int x, y, op, id;
}a[N];
int n, col[N * 2], tot;
int ans[N], KK_, sta[N * 2], du[N * 2];
vector <int> G[N * 2], F[N * 2], F_[N * 2];
bool in[N * 2], use[N * 2];
int zf, re; char c;
int read() {
zf = 1; re = 0; c = getchar();
while (c < '0' || c > '9') {
if (c == '-') zf = -zf;
c = getchar();
}
while (c >= '0' && c <= '9') {
re = (re << 3) + (re << 1) + c - '0';
c = getchar();
}
return re * zf;
}
bool cmpx(node x, node y) {
if (x.x != y.x) return x.x < y.x; return x.y < y.y;}
bool cmpy(node x, node y) {
if (x.y != y.y) return x.y < y.y; return x.x < y.x;}
void add(int x, int y) {
G[x].push_back(y); G[y].push_back(x);
}
//0:light edge
//1:same color edge
//2:INF边
bool Find;
void dfs(int now, int father) {
sta[++sta[0]] = now; in[now] = 1;
for (int i = 0; i < G[now].size(); i++)
if (G[now][i] != father) {
if (in[G[now][i]]) {
tot++; Find = 1;
while (sta[0]) col[sta[sta[0]]] = tot, sta[0]--;
return ;
}
else dfs(G[now][i], now);
if (Find) return ;
}
}
void Add(int x, int y, int z) {
F[x].push_back(y); if (x != y) F[y].push_back(x);
F_[x].push_back(z); if (x != y) F_[y].push_back(z);
du[x]++; du[y]++;
}
void Link() {
sort(a + 1, a + n + 1, cmpy);
for (int L = 1, R; L <= n; L = R + 1) {
R = L; while (R < n && a[R + 1].y == a[L].y) R++;
for (int i = L; i < R; i++) {
add(n + a[i].id, a[i + 1].id);
}
}
sort(a + 1, a + n + 1, cmpx);
for (int L = 1, R; L <= n; L = R + 1) {
R = L; while (R < n && a[R + 1].x == a[L].x) R++;
for (int i = L; i < R; i++) {
if (a[i].op == 0 && a[i + 1].op == 0) add(a[i].id, n + a[i + 1].id);
if (a[i].op == 0 && a[i + 1].op == 1) add(a[i].id, a[i + 1].id);
if (a[i].op == 1 && a[i + 1].op == 0) add(n + a[i].id, n + a[i + 1].id);
if (a[i].op == 1 && a[i + 1].op == 1) add(n + a[i].id, a[i + 1].id);
}
}
for (int i = 1; i <= 2 * n; i++)
if (!in[i]) {
sta[0] = 0, Find = 0, dfs(i, 0);
if (!Find) {
while (sta[0]) use[sta[sta[0]]] = 1, sta[0]--;
}
}
for (int i = 1; i <= n; i++) {
int x = use[i] ? 2 * n + 1 : col[i];
int y = use[n + i] ? 2 * n + 1 : col[n + i];
Add(x, y, i);
}
}
bool check_ans() {
for (int i = 1; i <= tot; i++)
if (du[i] % 8 != 0) return 0;
return 1;
}
struct nde {
int id, to, nxt;
}e[N * 2];
int in_[N * 2], le[N * 2], KK;
void run_way(int now) {
for (int i = le[now]; i; i = le[now]) {
le[now] = e[i].nxt;
if (in_[e[i].id]) continue; in_[e[i].id] = 1;
run_way(e[i].to); sta[++sta[0]] = e[i].id;
}
}
void get_oula() {
memset(in_, 0, sizeof(in_)); sta[0] = 0;
run_way(2 * n + 1);
for (int i = 1; i <= tot; i++) run_way(i);
for (int i = 1; i <= sta[0]; i += 2)
in_[sta[i]]++;
}
void clear() {
KK = 0; memset(le, 0, sizeof(le));
}
void slove() {
clear();
for (int i = 1; i <= 2 * n + 1; i++)
for (int j = 0; j < F[i].size(); j++)
e[++KK] = (nde){
F_[i][j], F[i][j], le[i]}, le[i] = KK;
get_oula();
for (int i = 1; i <= n; i++) ans[i] = in_[i] * 2;
clear();
for (int i = 1; i <= 2 * n + 1; i++)
for (int j = 0; j < F[i].size(); j++)
if (ans[F_[i][j]] == 2)
e[++KK] = (nde){
F_[i][j], F[i][j], le[i]}, le[i] = KK;
get_oula();
for (int i = 1; i <= n; i++) if (in_[i]) ans[i] += in_[i] - 2;
clear();
for (int i = 1; i <= 2 * n + 1; i++)
for (int j = 0; j < F[i].size(); j++)
if (ans[F_[i][j]] == 4)
e[++KK] = (nde){
F_[i][j], F[i][j], le[i]}, le[i] = KK;
get_oula();
for (int i = 1; i <= n; i++) if (in_[i]) ans[i] += in_[i] - 2;
for (int i = 1; i <= n; i++) printf("%d ", ans[i]);
}
int main() {
// freopen("pinball.in", "r", stdin);
// freopen("pinball.out", "w", stdout);
n = read();
for (int i = 1; i <= n; i++) {
a[i].x = read(); a[i].y = read(); a[i].id = i;
char c = getchar(); while (c != '\\' && c != '/') c = getchar();
if (c == '/') a[i].op = 0; else a[i].op = 1;
}
Link();
if (!check_ans()) {
printf("-1"); return 0;}
slove();
return 0;
}
边栏推荐
猜你喜欢
adb shell error error: device unauthorized
Premiere Pro 2022 for (pr 2022)v22.5.0
使用 Postman 工具高效管理和测试 SAP ABAP OData 服务的试读版
Go1.18升级功能 - 模糊测试Fuzz 从零开始Go语言
基于C语言的编译器设计与实现
Intelligent bin (9) - vibration sensor (raspberries pie pico implementation)
Foreign media right, apple on May be true in inventory
js的toString方法
研发过程中的文档管理与工具
i.MX6ULL驱动开发 | 33 - NXP原厂网络设备驱动浅读(LAN8720 PHY)
随机推荐
Premiere Pro 2022 for (pr 2022)v22.5.0
联邦学习:联邦场景下的多源知识图谱嵌入
二分查找的细节坑
动态规划(一)
Masterless replication system (1) - write DB when node fails
Graham's Scan method for solving convex hull problems
Golang 小数操作之判断几位小数点与四舍五入
【7.29】Code Source - 【Arrangement】【Stone Game II】【Cow and Snacks】【Minimum Number of Spawns】【Sequence】
牛客网刷题(二)
2022年必读的12本机器学习书籍推荐
【愚公系列】2022年07月 Go教学课程 020-Go容器之数组
复杂高维医学数据挖掘与疾病风险分类研究
LevelSequence源码分析
华为顶级工程师历时9年总结的“趣谈网络协议”PDF文档,太强了
Single-cell sequencing workflow (single-cell RNA sequencing)
form 表单提交后,使页面不跳转[通俗易懂]
Applicable Scenarios of Multi-Master Replication (1) - Multi-IDC
牛客 HJ17 坐标移动
The 2nd China PWA Developer Day
[7.28] Code Source - [Fence Painting] [Appropriate Pairs (Data Enhanced Version)]