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");
    }
}

猜你喜欢

转载自www.cnblogs.com/suika/p/10205192.html