bzoj 3417: Poi2013 Tales of seafaring bfs

来源:互联网 发布:打折7折怎么算法 编辑:程序博客网 时间:2024/04/20 07:57

题意

一个n点m边无向图,边权均为1,有k个询问,每次询问给出(s,t,d),要求回答是否存在一条从s到t的路径,长度为d,路径不必是简单路(可以自交)。
n,m<=5000,k<=1000000,d<=1000000000

分析

考虑到若从s可以走d步到达t,则s必然可以走t+2步到达t,所以只要从每个点开始看该点能否通过奇数步或偶数步到达某个点即可。

代码

#include<iostream>#include<cstdio>#include<cstdlib>#include<cstring>#include<algorithm>#include<queue>#define N 5005using namespace std;int n,m,k,cnt,last[N],dis[N][2],vis[N],ls[N];queue <int> q;struct edge{int to,next;}e[N*2];struct query{int dis,to,next,ans;}a[1000005];int read(){    int x=0,f=1;char ch=getchar();    while (ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}    while (ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}    return x*f;}void addedge(int u,int v){    e[++cnt].to=v;e[cnt].next=last[u];last[u]=cnt;    e[++cnt].to=u;e[cnt].next=last[v];last[v]=cnt;}void bfs(int s){    for (int i=last[s];i;i=e[i].next)    {        dis[e[i].to][1]=vis[e[i].to]=1;        q.push(e[i].to);    }    while (!q.empty())    {        int u=q.front();        q.pop();        for (int i=last[u];i;i=e[i].next)        {            if (dis[u][0]&&!dis[e[i].to][1])            {                dis[e[i].to][1]=dis[u][0]+1;                if (!vis[e[i].to])                {                    vis[e[i].to]=1;                    q.push(e[i].to);                }            }            if (dis[u][1]&&!dis[e[i].to][0])            {                dis[e[i].to][0]=dis[u][1]+1;                if (!vis[e[i].to])                {                    vis[e[i].to]=1;                    q.push(e[i].to);                }            }        }        vis[u]=0;    }}int main(){    n=read();m=read();k=read();    for (int i=1;i<=m;i++)    {        int x=read(),y=read();        addedge(x,y);    }    for (int i=1;i<=k;i++)    {        int x=read(),y=read(),z=read();        a[i].to=y;a[i].dis=z;a[i].next=ls[x];ls[x]=i;    }    for (int i=1;i<=n;i++)    {        memset(dis,0,sizeof(dis));        bfs(i);        for (int j=ls[i];j;j=a[j].next)            if (dis[a[j].to][a[j].dis%2]&&a[j].dis>=dis[a[j].to][a[j].dis%2]) a[j].ans=1;    }    for (int i=1;i<=k;i++)        if (a[i].ans) printf("TAK\n");        else printf("NIE\n");    return 0;}
0 1
原创粉丝点击