【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\n");
else printf("NIE\n");
return 0;
}