【BZOJ3417】[POI2013]MOR-Tales of seafaring (最短路SPFA)

[POI2013]MOR-Tales of seafaring

题目描述

一个n点m边无向图,边权均为1,有k个询问

每次询问给出(s,t,d),要求回答是否存在一条从s到t的路径,长度为d

路径不必是简单路(可以自交)

输入样例#1:

8 7 4
1 2
2 3
3 4
5 6
6 7
7 8
8 5
2 3 1
1 4 1
5 5 8
1 8 10

输出样例#1:

TAK
NIE
TAK
NIE

题解

没有时间了,先放代码,明天补坑。。。

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cctype>
#include<queue>
#include<vector>
#define N 5005
#define INF 0x3f3f3f3f
#define R register
using namespace std;
template<typename T>inline void read(T &a){
	char c=getchar();T x=0,f=1;
	while(!isdigit(c)){if(c=='-')f=-1;c=getchar();}
	while(isdigit(c)){x=(x<<1)+(x<<3)+c-'0';c=getchar();}
	a=f*x;
}
vector<int> t[N];
int n,m,k,tot,h[N];
bool vis[N],ans[1000005];
int dis[2][N];
struct query{
	int u,v,w;
}q[1000005];
struct node{
	int nex,to;
}edge[N<<1];
inline void add(R int u,R int v){
	edge[++tot].nex=h[u];
	edge[tot].to=v;
	h[u]=tot;
}
inline void spfa(R int s){
	queue<int> Q;
	for(R int i=1;i<=n;i++)dis[0][i]=INF,dis[1][i]=INF,vis[i]=0;
	Q.push(s);vis[s]=1;dis[0][s]=0;
	while(!Q.empty()){
		R int x=Q.front();Q.pop();vis[x]=0;
		for(R int i=h[x];i;i=edge[i].nex){
			R int xx=edge[i].to,flg=0;
			if(dis[0][x]!=INF){
				if(dis[1][xx]>dis[0][x]+1)
					dis[1][xx]=dis[0][x]+1,flg=1;
			}
			if(dis[1][x]!=INF){
				if(dis[0][xx]>dis[1][x]+1)
					dis[0][xx]=dis[1][x]+1,flg=1;
			}
			if(flg&&!vis[xx])Q.push(xx),vis[xx]=1;
		}
	}
}
int main(){
	read(n);read(m);read(k);
	for(R int i=1,u,v;i<=m;i++){
		read(u);read(v);
		add(u,v);add(v,u);
	}
	for(R int i=1;i<=k;i++){
		read(q[i].u),read(q[i].v),read(q[i].w);
		t[q[i].u].push_back(i);
	}
	for(R int i=1;i<=n;i++){
		if(!t[i].size())continue;
		spfa(i);
		for(R int j=0;j<t[i].size();j++){
			R int o=t[i][j];
			R int num=q[o].w%2;
			if(q[o].w>=dis[num][q[o].v]&&h[i])ans[o]=1;
		}
	}
	for(R int i=1;i<=k;i++)
		if(ans[i])printf("TAK
");
		else printf("NIE
");
	return 0;
}
原文地址:https://www.cnblogs.com/ZAGER/p/9846461.html