我们可以在两个点之间来回反复,所以问题就变成了判断两点之间道路条数为奇数或偶数的最短路是否小于等于d
分成图,边都跨层连,即可算出奇数最短路和偶数最短路
注意特判孤立点询问自己的情况
#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<ctime>
#include<cmath>
#include<algorithm>
#include<iomanip>
#include<vector>
#include<map>
#include<set>
#include<bitset>
#include<queue>
#include<stack>
using namespace std;
#define MAXN 10010
#define MAXM 1000010
#define INF 1000000000
#define MOD 1000000007
#define eps 1e-8
#define ll long long
struct vec{
int to;
int fro;
};
struct data{
int y;
int v;
int num;
data(){
}
data(int _y,int _v,int _num){
y=_y;
v=_v;
num=_num;
}
};
vec mp[MAXN*2];
int tai[MAXN],cnt;
bool abl[MAXM];
vector<data>que[MAXN];
int d[MAXN];
int q[MAXN],hd,tl;
int n,m,Q;
inline void be(int x,int y){
mp[++cnt].to=y;
mp[cnt].fro=tai[x];
tai[x]=cnt;
}
void bfs(int x){
int i,y;
memset(d,-1,sizeof(d));
d[x]=0;
hd=tl=0;
q[tl++]=x;
while(hd!=tl){
x=q[hd++];
for(i=tai[x];i;i=mp[i].fro){
y=mp[i].to;
if(d[y]==-1){
d[y]=d[x]+1;
q[tl++]=y;
}
}
}
}
int main(){
int i,j,x,y,z;
scanf("%d%d%d",&n,&m,&Q);
for(i=1;i<=m;i++){
scanf("%d%d",&x,&y);
be(x,n+y);
be(y,n+x);
be(n+x,y);
be(n+y,x);
}
for(i=1;i<=Q;i++){
scanf("%d%d%d",&x,&y,&z);
que[x].push_back(data(y,z,i));
}
for(i=1;i<=n;i++){
bfs(i);
for(j=0;j<que[i].size();j++){
if(hd==1&&que[i][j].y==i&&que[i][j].v){
continue ;
}
if(d[que[i][j].y+(que[i][j].v&1)*n]<=que[i][j].v&&d[que[i][j].y+(que[i][j].v&1)*n]>=0){
abl[que[i][j].num]=1;
}
}
}
for(i=1;i<=Q;i++){
printf(abl[i]?"TAK\n":"NIE\n");
}
return 0;
}
/*
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
*/