当前位置:网站首页>F - true liars (category and search set +dp)
F - true liars (category and search set +dp)
2022-07-06 06:14:00 【RCyyds】
Portal : True Liars


The question : give n To the relationship ,p1 I'm a good man ,p2 I'm a bad guy . Requirements according to n Find out what good people are in the relationship , If the scheme is unique , Then output good people one by one , The final output end; If the scheme is not unique / Can't find , Then output no
Ideas : It's the first time to encounter this type of problem , After thinking for a long time, I have no idea , Refer to others' blogs Just understand .
The following is the idea of the referenced blog :
Through simple analysis, we can get , For each relationship (x,y,yes/no), If the relationship is yes, be x and y Belong to the same category ; If the relationship is no, be x and y Belong to the opposite class .
According to the preliminary n To the relationship , We can only introduce those who belong to the same category , Which people belong to the opposite category , But it's not sure what kind of good people are / The bad guys . We can define the opposite two kinds of people as a large set , Then there are two small sets in the large set . According to the meaning , We just need from each large set , Choose one of the small sets , Make the total number of people in all the selected small sets be p1 that will do .
Code :
#include <cstdio>
#include <cstring>
#include <iostream>
#define MAXN 600
using namespace std;
int parent[MAXN], path[MAXN][MAXN], dp[MAXN][MAXN];
int num[MAXN]; // Record that the root node of the large set is i Yes, it is num[i] A large collection
int flag[MAXN][2]; // Mark the small set selected to the final result in each large set
int cnt[MAXN][2]; // The root node is i when , Record the number of people contained in the two small sets
int relat[MAXN];
/* relation
* relat=0/1.0 Express i And root nodes parent[i] Related to , That is, it belongs to the same small set ;1 Express i Not associated with root node , That is, different small sets belonging to the same large set */
int find(int x) {
if (x != parent[x]) { // Here parent[x] It's the old father
int px = find(parent[x]); // px It's the new father
relat[x] ^= relat[parent[x]];
/* Due to path compression x The parent node of points directly to the root node , That is, it changes x The father node of , So update the node x Relationship with root node .
*/
parent[x] = px;
}
return parent[x];
}
/*
about "relat[x] ^= relat[parent[x]];" XOR interpretation :
It can be concluded through simple analysis :
1. If ( relation[x And old father ]=0 && relation[ Old father and new father ]=0 ) perhaps (
relation[x And old father ]=1 && relation[ Old father and new father ]=1 ), be relation[x And the new father ]=0
2. If (relation[x And old father ]=1 && relation[ Old father and new father ]=0 ) perhaps (
relation[x And old father ]=0 && relation[ Old father and new father ]=1 ), be relation[x And the new father ]=1
You can find , Final relatino[x And the new father ] = relation[x And old father ] ^ relation[ Old father and new father ]
namely : relat[x] ^= relat[parent[x]];
For the following merge XOR in function is the same
*/
void merge(int x, int y, int d) { // d Either for 0, Either for 1
int px = find(x);
int py = find(y);
if (px != py) {
parent[py] = px;
relat[py] = relat[x] ^ relat[y] ^ d;
}
}
int main(void) {
int m, p, q;
while (scanf("%d%d%d", &m, &p, &q)) {
if (m + p + q == 0) {
break;
}
for (int i = 1; i <= p + q; i++) { //** Initial remarks
relat[i] = 0;
parent[i] = i;
}
while (m--) {
int x, y, d = 1;
char ch[5];
scanf("%d%d%s", &x, &y, ch);
if (ch[0] == 'y') {
d = 0;
}
merge(x, y, d);
}
memset(num, 0, sizeof(num)); //**num Store the number of sets and number them
memset(path, 0, sizeof(path));
memset(cnt, 0, sizeof(cnt));
memset(dp, 0, sizeof(dp));
memset(flag, 0, sizeof(flag));
int tot = 0;
for (int i = 1; i <= p + q; i++) { //** Count the number of sets and number
if (find(i) == i) {
num[i] = ++tot; // tot Number of connected blocks ,num Record root=i The number of the connected block of
}
}
for (int i = 1; i <= p + q;
i++) { //** Count the number of two types of each set and store them in cnt in
cnt[num[find(i)]][relat[i]]++;
}
dp[0][0] = 1;
for (int i = 1; i <= tot; i++) { // tot=2
for (int j = 0; j <= p+q; j++) { // p+q=7
//**dp[i][j] Store to page i Select the kind and for sets j The number of ways
if (j - cnt[i][0] >= 0 && dp[i - 1][j - cnt[i][0]]) {
dp[i][j] += dp[i - 1][j - cnt[i][0]];
path[i][j] =
cnt[i][0]; //**path Array record path , That is 1 still 0
}
if (j - cnt[i][1] >= 0 && dp[i - 1][j - cnt[i][1]]) {
dp[i][j] += dp[i - 1][j - cnt[i][1]];
path[i][j] = cnt[i][1];
}
}
}
/*
There are two in this part if It's a little hard to understand , Because you may think , Two if If you are satisfied , So the final result is dp[i][j] It is possible that two small sets are selected from the same large set , It's against “ Select only one small set from a large set ” The situation of . but , You can find , We finally limited the number of methods to dp[tot][p]=1 when , There is only one plan . If it's like the two just mentioned if All satisfied with , that dp[i][j] A certain >1, It will not meet the following dp[tot][p]=1 Limit , So it solved the problem .
*/
if (dp[tot][p] != 1) {
printf("no\n");
} else {
for (int i = tot, j = p; j > 0 && i > 0; i--) { //** Tag path
if (path[i][j] == cnt[i][0]) {
flag[i][0] = 1;
} else {
flag[i][1] = 1;
}
j -= path[i][j];
// Remember to reduce . Because I just choose enough backpacks p, So follow p Gradually reduce the items at that time , Find the way
}
for (int i = 1; i <= p + q; i++) {
if (flag[num[find(i)]][relat[i]]) {
printf("%d\n", i);
}
}
printf("end\n");
}
}
return 0;
}
边栏推荐
- [postman] dynamic variable (also known as mock function)
- MySQL之基础知识
- 假设检验学习笔记
- 「 WEB测试工程师 」岗位一面总结
- Bit operation rules
- Pat (Grade B) 2022 summer exam
- Summary of anomaly detection methods
- Network protocol model
- Coordinatorlayout+nestedscrollview+recyclerview pull up the bottom display is incomplete
- Sqlmap tutorial (III) practical skills II
猜你喜欢

LeetCode 729. 我的日程安排表 I

Expose the serial fraudster Liu Qing in the currency circle, and default hundreds of millions of Cheng Laolai

Detailed explanation of BF and KMP

What are the test sites for tunnel engineering?
![Buuctf-[[gwctf 2019] I have a database (xiaoyute detailed explanation)](/img/2c/43ce298794589c5282edda94161d62.jpg)
Buuctf-[[gwctf 2019] I have a database (xiaoyute detailed explanation)
![[web security] nodejs prototype chain pollution analysis](/img/c5/256ab30e796f0859387585873cee8b.jpg)
[web security] nodejs prototype chain pollution analysis

Application of Lie group in gtsam

The latest 2022 review of "graph classification research"

LeetCode 1200. 最小绝对差

单元测试的意义
随机推荐
【无App Push 通用测试方案
isam2运行流程
通过修改style设置打印页样式
【LeetCode】Day96-第一个唯一字符&赎金信&字母异位词
Linux regularly backs up MySQL database
[C language] qsort function
Cannot create PoolableConnectionFactory (Could not create connection to database server. 错误
IP day 16 VLAN MPLS configuration
Arrays and collections
Bit operation rules
The latest 2022 review of "graph classification research"
Testing and debugging of multithreaded applications
Introduction to promql of # yyds dry goods inventory # Prometheus
【API接口工具】postman-界面使用介绍
Software test interview questions - Test Type
How Huawei routers configure static routes
曼哈顿距离和-打印菱形
【Postman】Monitors 监测API可定时周期运行
MySQL之基础知识
Idea new UI usage