BZOJ3417: Poi2013 Tales of seafaring

BZOJ3417: Poi2013 Tales of seafaring

https://lydsy.com/JudgeOnline/problem.php?id=3417

分析:

  • 题中说了是无向图,那么所有边都可以看做是长度为\(2\)的环。
  • 那么只需要处理出任意两点之间的奇偶最短路即可。
  • 这里用short存的。

代码:

#include <cstdio>
#include <cstring>
#include <algorithm>
#include <iostream>
#include <cmath>
using namespace std;
#define N 5050
char buf[100000],*p1,*p2;
#define nc() (p1==p2&&(p2=(p1=buf)+fread(buf,1,100000,stdin),p1==p2)?EOF:*p1++)
int rd() {
	int x=0; char s=nc();
	while(s<'0') s=nc();
	while(s>='0') x=(((x<<2)+x)<<1)+s-'0',s=nc(); return x;
}
int head[N],to[N<<1],nxt[N<<1],cnt,n,m,Q[N<<1],vis[N];
short dis[N][N][2];
inline void add(int u,int v) {
	to[++cnt]=v; nxt[cnt]=head[u]; head[u]=cnt;
}
int main() {
	int q;
	n=rd(),m=rd(),q=rd();
	int i,x,y,s;
	for(i=1;i<=m;i++) x=rd(),y=rd(),add(x,y),add(y,x);
	for(s=1;s<=n;s++) {
		int l=0,r=0;
		for(i=head[s];i;i=nxt[i]) {
			dis[s][to[i]][1]=1; Q[r++]=to[i]; dis[s][s][0]=1; vis[to[i]]=1; if(!vis[s]) vis[s]=1,Q[r++]=s;
		}
		while(l!=r) {
			x=Q[l++]; vis[x]=0; if(l==n+1) l=0;
			for(i=head[x];i;i=nxt[i]) {
				y=to[i];
				if((!dis[s][y][1]||dis[s][y][1]>dis[s][x][0]+1)&&dis[s][x][0]) {
					dis[s][y][1]=dis[s][x][0]+1;
					if(!vis[y]) Q[r++]=y,vis[y]=1,(r>n?(r=0):0);
				}
				if((!dis[s][y][0]||dis[s][y][0]>dis[s][x][1]+1)&&dis[s][x][1]) {
					dis[s][y][0]=dis[s][x][1]+1;
					if(!vis[y]) Q[r++]=y,vis[y]=1,(r>n?(r=0):0);
				}
			}
		}
	}
	while(q--) {
		int t,d;
		s=rd(),t=rd(),d=rd();
		puts(dis[s][t][d&1]-1<=d&&dis[s][t][d&1]?"TAK":"NIE");
	}
}
posted @ 2019-01-01 16:56  fcwww  阅读(...)  评论(...编辑  收藏