Codeforces 28B pSort(dfs,判断连通)

E - pSort
Time Limit:2000MS     Memory Limit:262144KB     64bit IO Format:%I64d & %I64u

Description

One day n cells of some array decided to play the following game. Initially each cell contains a number which is equal to it's ordinal number (starting from 1). Also each cell determined it's favourite number. On it's move i-th cell can exchange it's value with the value of some other j-th cell, if |i - j| = di, where di is a favourite number of i-th cell. Cells make moves in any order, the number of moves is unlimited.

The favourite number of each cell will be given to you. You will also be given a permutation of numbers from 1 to n. You are to determine whether the game could move to this state.

Input

The first line contains positive integer n (1 ≤ n ≤ 100) — the number of cells in the array. The second line contains n distinct integers from 1 to n — permutation. The last line contains n integers from 1 to n — favourite numbers of the cells.

Output

If the given state is reachable in the described game, output YES, otherwise NO.

Sample Input

Input
5
5 4 3 2 1
1 1 1 1 1
Output
YES
Input
7
4 3 5 1 2 7 6
4 6 6 1 6 6 1
Output
NO
Input
7
4 2 5 1 3 7 6
4 6 6 1 6 6 1
Output
YES

思路:用vector储存每个点可以交换的点,然后深搜看能否通过交换得到现有的序列,即判断这两个点是否可以连通。

代码如下:

#include<iostream>
#include<vector>
#include<cstring>
using namespace std;
int target[110];//储存目标序列 
vector<int>v[110];
bool vis[110][110];//已访问标记数组 
bool dfs(int st,int cur,int ed){//深搜 
	vis[st][cur]=1;
	if(cur==ed)return 1;//如果通过深搜找到了目标点,即连通 
	for(int i=0;i<v[cur].size();i++){
		if(!vis[st][v[cur][i]]){
			if(dfs(st,v[cur][i],ed))return 1;
		}
	}
	return 0;
}
int main(){
    int n,i,j,d;
    cin>>n;
    for(i=1;i<=n;i++)
    cin>>target[i];
    for(i=1;i<=n;i++){
    	v[i].push_back(i);
    	cin>>d;
    	if(i+d<=n){
	    	v[i].push_back(i+d);//i可以连通到i+d 
	    	v[i+d].push_back(i);//因为是无向图,i+d也可以联通到i 
	    }
	    if(i-d>=1){
    		v[i].push_back(i-d);//i可以连通到i-d 
    		v[i-d].push_back(i);//因为是无向图,i-d也可以联通到i
    	}
    }
    int flag1=1;
    for(i=1;i<=n;i++){
    	if(!dfs(i,i,target[i]))flag1=0;//如果有一个点与无法交换到目标的点,即该点与目标点不连通,就输出NO 
    }
    if(flag1)cout<<"YES"<<endl;
    else cout<<"NO"<<endl;
	return 0;
} 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值