最初のCCFコンピュータソフトウェアコンピテンシー認定ワイヤレスネットワークspfaの4番目の質問

最初のCCFコンピュータソフトウェアコンピテンシー認定
4番目の質問ワイヤレスネットワークspfa

注:最初にグラフを作成するとき、2つのポイント間の距離が爆発します
。intdis[i] [num]は、開始位置からポイントiまでの最短の長さを示し、num個の特別なポイントを通過します
。vis[i] [num]はのキューにあるかどうか

結果はmin [2] [kk]で、kk = 0〜k2が終点です。

#include<iostream>
#include<cstring>
#include<algorithm>
#include<cmath>
using namespace std;
#include<queue>

typedef long long LL;
typedef pair<int,int> PII;

const int max_n=210;
const int max_m=210*210;

int bes_dis=0x1f1f1f1f;

int dis[max_n][105];
int vis[max_n][105];


int kind[max_n];
int beg,endd;

int idx;
int h[max_n];
int ne[max_m];
int e[max_m];

int n,m,k;
LL r;


struct Point{
    
    
	int x,y;
}PP[max_n];


void add(int u,int v)
{
    
    
	e[idx]=v;
	ne[idx]=h[u];
	h[u]=idx++;
}

queue<PII> qq;

int dd(int u,int v)
{
    
    
	if(LL(PP[u].x-PP[v].x)*(PP[u].x-PP[v].x)+LL(PP[u].y-PP[v].y)*(PP[u].y-PP[v].y)<=r*r )
		return 1;
	else return 0;
}

void init()
{
    
    
	memset(h,-1,sizeof(h));
}

void  spfa()
{
    
    
	memset(dis,0x1f1f1f,sizeof(dis));
	memset(vis,0,sizeof(vis));
	
	dis[beg][0]=0;
	vis[beg][0]=1;
	qq.push({
    
    beg,0});
	
	while(!qq.empty())
	{
    
    
		PII tt=qq.front();
		qq.pop();
		
		vis[tt.first][tt.second]=0;//出队 vis变为0
		
		int next,next_num;
		
		for(int i=h[tt.first];~i;i=ne[i])
		{
    
    
			next=e[i];
			
			if(kind[next])
				next_num=tt.second+1;
			else next_num=tt.second;
			
	
			if(next_num<=k && dis[next][next_num]>dis[tt.first][tt.second]+1) //<=k进行减枝
			{
    
    
				dis[next][next_num]=dis[tt.first][tt.second]+1;
				
				if(!vis[next][next_num])   //更新距离和进队不完全同步
				{
    
    
					qq.push({
    
    next,next_num});
					vis[next][next_num]=1;
				}	
		
			}			
			
		}
		
	}
	
	int minn=0x1f1f1f1f; 
	for(int i=0;i<=k;i++)
	{
    
    
		minn=min(minn,dis[endd][i]);
	}
	
	cout<<minn-1;
	
}


int main()
{
    
    
	cin>>n>>m>>k>>r;
	
	beg=1;
	endd=2;

	init();

	for(int i=1;i<=n;i++)
	{
    
    
		scanf("%d%d",&PP[i].x,&PP[i].y);
		kind[i]=0;
		
		for(int j=1;j<i;j++)
		{
    
    
			if(dd(i,j))
			{
    
    
				add(i,j);
				add(j,i);
			}
		}
		
	}
	
	for(int i=1;i<=m;i++)
	{
    
    
		scanf("%d%d",&PP[i+n].x,&PP[i+n].y);
		
		kind[i+n]=1;
		
		for(int j=1;j<i+n;j++)
		{
    
    
			if(dd(i+n,j))
			{
    
    
				add(i+n,j);
				add(j,i+n);
			}
		}
	}
	
	
	spfa();
	
	 	
	return 0;
 } 

おすすめ

転載: blog.csdn.net/weixin_45448563/article/details/114004791