P5663 machined parts solution to a problem

Original title link

Briefly meaning of the questions:

Given a graph, each query from \ (X \) start node, \ (Y \) step can not reach \ (1 \) number of nodes.

A algorithm

This is my own examination algorithm. It is deep search .

Because you will find that if \ (x \) with \ (y \% 2 \) Step able to \ (1 \) node, it is certainly \ (y \) Step able to.

The reason: the rest of the \ (y - y \% 2 \) is even, just repeat many times to take a side.

We \ (f_ {i, 0/ 1} \) represents from \ (I \) No. node through even number step (0) odd number step (1) to go to \ (1 \) Minimum number of nodes of the number of steps.

From \ (1 \) began to search deep. If you already have the answer to the current answer better, it is ended.

Time complexity: \ (O (n-2 ^) \) (will be explained after the code).

Actual score: \ (80pts \) (also so much on the test).

#pragma GCC optimize(2)
#include<bits/stdc++.h>
using namespace std;

const int N=1e5+1;

inline int read(){char ch=getchar();int f=1;while(ch<'0' || ch>'9') {if(ch=='-') f=-f; ch=getchar();}
	int x=0;while(ch>='0' && ch<='9') x=(x<<3)+(x<<1)+ch-'0',ch=getchar();return x*f;}

int f[N][2];
int n,m,q;
vector<int>G[N];

inline void dfs(int dep,int bs) {
	if(f[dep][bs%2]!=-1 && f[dep][bs%2]<=bs) return; //无需更新答案
	f[dep][bs%2]=bs; //记录答案
	for(int i=0;i<G[dep].size();i++) {
		int x=G[dep][i];
		dfs(G[dep][i],bs+1);
	}
}

int main(){
	n=read(),m=read(),q=read();
	memset(f,-1,sizeof(f));
	while(m--) {
		int x=read(),y=read();
		G[x].push_back(y);
		G[y].push_back(x);
	} f[1][0]=2; dfs(1,0);
	while(q--) {
		int x=read(),y=read();
		if(f[x][y%2]!=-1 && f[x][y%2]<=y) puts("Yes");
		else puts("No");
	} //判断
	return 0;
}

Would you say, the time complexity of this program is \ (O (n) \) , right? How is \ (O (the n-^ 2) \) ?

This problem also plagued me for a long time, that it's hard to think clearly, what kind of situation can be snapped out of it.

After rewriting the code found.

Because, if it is a complete graph, each point will be other points of arrival (despite being \ (\ texttt {return} \ ) but still do), it is \ (O (n-2 ^) \) .

Would you say, that will not be the complete graph ah? \ (n \) and \ (m \) is of the same order ah?

Right. So do not consider the complete graph, given graph is certainly sparse graphs.

So, where are the problem?

You think if the original image is a long \ (10 ^ 5 \) is a ring.

At this point, the program is likely to blow up.

Because, if you traversal order all the way to finish this ring, then walked again (because of different parity, leading to walk \ (2 \) times).

Then, the number of times each point to explore the inside of \ (2 \) , which means that each point began to explore other points.

But let's say you go in the third ring when \ (1 \) to end off, then \ (n \) number of nodes to return to \ (n-1 \) number of nodes.

Then \ (n-1 \) recursion node number becomes \ (2 \) , which fell upon the sides of the pan, but also to the \ (n-\) , and then ended.

Each point regarded himself pot (that is, recursion) adjacent to throw, however, you have to go \ (n \) times (on the head) before they can determine the answer to a node.

At this time, \ (O (^ n-2) \) .

So, how to optimize this process?

Algorithms two

Not deep search, with a wide search.

With a wide search does not exist, "another rejection pot," this issue. Everyone will often dumped several pot.

Time complexity: \ (O (n-m +) \) . ( N-\ (\) has coefficients, but ignored)

Actual score: \ (100 pts \) .

#pragma GCC optimize(2)
#include<bits/stdc++.h>
using namespace std;

const int N=1e5+1;

inline int read(){char ch=getchar();int f=1;while(ch<'0' || ch>'9') {if(ch=='-') f=-f; ch=getchar();}
	int x=0;while(ch>='0' && ch<='9') x=(x<<3)+(x<<1)+ch-'0',ch=getchar();return x*f;}

int f[N][2];
int n,m,q;
vector<int>G[N];

inline void bfs() {
	queue<pair<int,int> >q;
	memset(f,0x3f,sizeof(f));
	for(int i=0;i<G[1].size();i++) {
		f[G[1][i]][1]=1; //与1相邻的点,奇数步能到达1
		q.push(make_pair(G[1][i],1)); //入队
	} while(!q.empty()) {
		int x=q.front().first,y=q.front().second;
		q.pop();
		for(int i=0;i<G[x].size();i++) {
			int k=G[x][i];
			if(y+1<f[k][1-y%2]) {
				f[k][1-y%2]=y+1;
				q.push(make_pair(k,y+1)); //入队
			} //1-y%2,就是 (y+1)%2,改变奇偶性后 0->1,1->0,正好用 1 减掉。
		}
	}
}

int main(){
	n=read(),m=read(),q=read();
	while(m--) {
		int x=read(),y=read();
		G[x].push_back(y);
		G[y].push_back(x);
	} bfs();
	while(q--) {
		int x=read(),y=read();
		if(f[x][y%2]<=y) puts("Yes");
		else puts("No");
	}
	return 0;
}

postscript

This topic a couple of points:

  • Search does not have to open wide next to the hash.

  • Deep search sometimes difficult to deal with a great ring.

Guess you like

Origin www.cnblogs.com/bifanwen/p/12593318.html