UVA 10158 (记忆化搜索)
题目大意:
已知有n个人,他们之间有敌对还有友好关系,已知:
自己和自己为好友。
a和b为好友,那么b和a也为好友
自己的敌人是敌人。
自己和自己不能为敌人。
a和b为敌人,那么b和a也为敌人
敌人的敌人是朋友
现在有4个操作,比如:
(1)设置a和b为朋友
(2)设置a和b为敌人
(3)询问a和b是否为好友
(4)询问a和b是否为敌人
解题思路:
网上大部分的思路都是并查集。可是真的看不懂,太菜了,ORZ. 这里提出一种记忆化搜索加玄学剪枝的方法。
开一个1e4 * 1e4的二维数组。
memo[i][j] = -1 , 0, 1分别代表i和j是无关,朋友,敌人关系。
另外开一个有权图表示谁和谁之间建立了朋友或敌人关系。
其中边权为1代表是敌人,边权为0代表是朋友。
这题的关键是(3),(4)操作。比如(3)操作成立了,那么(2)操作就是非法,假若(2)操作合法了,我们只需要维护memo表更新并且gra连一条边即可。那么关键是(3)操作怎么完成。(4)操作类似。
定义dfs状态u,dis,u表示我们到达哪个节点,dis表示我们从根节点到u节点的边权之和。
首先第一个关系:
if(memo[u][desu]!=-1){ //memorize suc=(dis+memo[u][desu])%2;return;}
这里desu代表终点。表明若我们走到半路,之前这里已经建立关系了,我们可以不用走下去了。至于为什么模2,我们可以看看,我们发现边权累加到奇数,表示这时候根节点和u节点之间建立的是敌人关系,假如累积到偶数,表示根节点和u节点之间建立的是朋友关系。模2是用来表示朋友还是敌人的。
memo[u][initu]=dis%2; //pruningmemo[initu][u]=dis%2; //pruning
中间这里我们可以边走边填数字,俗称玄学剪枝。initu表示我们的起始根节点。
if(u==desu){suc=memo[u][desu];return;}
最后没什么好说的,我们走到终点停下来就好了。
完整代码:
#include <bits/stdc++.h>
using namespace std;
int initu,desu;
int suc=-1;
const int MAXN=1e4+10;
int memo[MAXN][MAXN];
int flag[MAXN];
vector<vector<pair<int,int>>> gra(MAXN);
//tmd search
void dfs(int u,int dis){if(memo[u][desu]!=-1){ //memorize suc=(dis+memo[u][desu])%2;return;}flag[u]=1;memo[u][initu]=dis%2; //pruningmemo[initu][u]=dis%2; //pruningif(u==desu){suc=memo[u][desu];return;}for(int i=0;i<(int)gra[u].size();i++){int nx=gra[u][i].first;int wei=gra[u][i].second;if(flag[nx])continue;dfs(nx,dis+wei);if(suc!=-1)return;}
}
int main(){int n;cin>>n;int c;memset(memo,-1,sizeof(memo));while(cin>>c>>initu>>desu &&(c||initu||desu)){memset(flag,0,sizeof(flag));suc=-1;if(c==3){dfs(initu,0);if(suc==-1 || suc==1)cout<<0<<endl;else cout<<1<<endl;continue;}else if(c==4){dfs(initu,0);if(suc==-1 || suc== 0)cout<<0<<endl;else cout<<1<<endl;continue;}else if(c==1){dfs(initu,0);if(suc==1){cout<<-1<<endl;continue;}else if(suc==0)continue;else {gra[initu].emplace_back(make_pair(desu,0));gra[desu].emplace_back(make_pair(initu,0));memo[initu][desu]=0;memo[desu][initu]=0;}}else {dfs(initu,0);if(suc==0){cout<<-1<<endl;continue;}else if(suc==1)continue;else {gra[initu].emplace_back(make_pair(desu,1));gra[desu].emplace_back(make_pair(initu,1));memo[initu][desu]=1;memo[desu][initu]=1;}}}return 0;
}
UVA 10158 (记忆化搜索)相关推荐
- UVa 10118 记忆化搜索 Free Candies
假设在当前状态我们第i堆糖果分别取了cnt[i]个,那么篮子里以及口袋里糖果的个数都是可以确定下来的. 所以就可以使用记忆化搜索. 1 #include <cstdio> 2 #inclu ...
- 【UVA 437】The Tower of Babylon(记忆化搜索写法)
[题目链接]:https://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_probl ...
- UVA - 10118Free Candies(记忆化搜索)
题目:UVA - 10118Free Candies(记忆化搜索) 题目大意:给你四堆糖果,每个糖果都有颜色.每次你都只能拿任意一堆最上面的糖果,放到自己的篮子里.如果有两个糖果颜色相同的话,就可以将 ...
- uva 707(记忆化搜索)
题意:在一个方阵中,一个强盗犯要逃跑.你是警察要去抓他,现在你手上有若干线索他们会告诉你第i时刻一个方阵中他们没有看见强盗.在t秒后全部道路会封锁.让你通过线索来判断是不是能够找到小偷在某一秒的位置. ...
- UVa 1629 切蛋糕(记忆化搜索)
https://vjudge.net/problem/UVA-1629 题意: 有一个n行m列的网格蛋糕上有一些樱桃.每次可以用一刀沿着网格线把蛋糕切成两块,并且只能直切不能拐弯.要求最后每一块蛋糕上 ...
- UVA - 10253 Series-Parallel Networks(递推式、记忆化搜索写法)
题目:UVA-10253 题目翻译(来自蓝书): 串并联网络有两个端点,一个叫源,一个叫汇,递归定义如下: (1) 一条单独的边是串并联网络. (2) 若G1和G2是串并联网络,把它们的源和源接在一起 ...
- UVA - 11361 Investigating Div-Sum Property(数位dp/记忆化搜索板子)
题目:https://vjudge.net/problem/UVA-11361 思路:数位dp,用记忆化搜索写,dp[pos][i][j][limit] 代表剩余有pos位,每位上的数字和模k 等于i ...
- uva 11762 数学期望+记忆化搜索
题目大意:给一个正整数N,每次可以在不超过N的素数中随机选择一个P,如果P是N的约数,则把N变成N/p,否则N不变,问平均情况下需要多少次随机选择,才能把N变成1? 分析:根据数学期望的线性和全期望公 ...
- uva 10118 - Free Candies(记忆化搜索)
题目大意:10118 - Free Candies 题目大意:有4堆糖果, 每堆糖果有n颗糖果,然后给出每颗糖果的类型1~20,然后只有取走当前堆的前面一颗糖果后才可以取后面的糖果, 然后小伙伴有一个 ...
最新文章
- XPath实例教程十四、following-sibling轴
- 基于ASP.NET的comet简单实现
- applecare多少钱?_否,AppleCare +无法覆盖丢失或被盗的iPhone
- php自动加载什么时候用到,php的自动加载的使用
- mysqld已删除但仍占用空间的_U盘删除的文件在哪?
- 计算机在档案部门应用范围,计算机在档案管理中的相关运用
- Visual Studio助手VAssistx各版本破解教程
- mysql chunk_【MySQL参数】-innodb_buffer_pool_chunk_size
- QT随手记:解决opencv播放USB视频延迟、拖影的方法
- 基于Python的数据结构实验——顺序表与单链表建立与操作(附详细代码和注释)
- 2015年智能家居大事记 合纵连横成主旋律
- gRPC详细入门教程,Golang/Python/PHP多语言讲解
- nodeJS xlsx库 笔记
- 华为高清会议摄像机预置位的使用方法
- 笔记:《深入浅出统计学》第八、九章:概率密度、正态分布(高斯分布)
- 经典PID控制算法原理以及优化思路
- C语言练习-统计数字个数
- ABBYY FineReader 14OCR解锁
- 斐波那契数列数列相关简化2
- java、正则表达式、php校验“统一社会信用代码”