五号点尝试dfs的蒟蒻求助

P1600 [NOIP2016 提高组] 天天爱跑步

Matrix_ @ 2019-11-11 01:54:15

什么都不会的蒟蒻尝试用最朴素的dfs过五号测试点的数据,但是遇到了问题。。。

暴力思想是:每次由玩家的起点开始进行dfs,直到找到玩家要到达的终点,flag标记为1,开始回溯。在回溯的时候比较时间戳与节点观察员出现时间是否匹配,若匹配则答案数组++。

样例数据中,在一二号玩家的处理上程序均正常执行,但在三号玩家处出现了问题。三号玩家由 2 -> 6 节点,程序在搜到三号点时无法正常回溯,不能到达二号点寻找一号点。

代码如下

代码中,dfs函数内,p表示当前所在位置,time表示已用时间,stop存储当前玩家目的地,dian[p].ans存放答案,dian[p].time表示该点出现察员的时间)

#include<iostream>
#include<cstdio>

using namespace std;

int n,m,p,a[10010],aa,bb,judge[10010],head[10010],ppp,book[10010],flag,cnt;

struct edge
{
    int u,v,w,next;
};
edge e[10010];

struct node
{
    int time,ans;
};
node dian[10010];
void addage(int u,int v)
{
    cnt++;
    e[cnt].u = u;
    e[cnt].v = v;
    //e[cnt].w = w;
    e[cnt].next = head[u];
    head[u] = cnt;
}

void dfs(int p,int time,int stop)
{
    printf("enter p=%d time = %d stop = %d book=%d flag=%d\n",p,time,stop,book[p],flag);
    if(book[p] == 1)
    {
        printf("111111\n");
        return ;
    }
    book[p] = 1;
    if(p == stop)
    {

        flag = 1;
        printf("found p=%d time=%d\n",p,time);
        if(dian[p].time == time)
        {
            dian[p].ans++;
            printf("lable dian[%d].ans = %d\n",p,dian[p].ans);
        }
        book[p] = 0;
        return ;
    }

    for(int i=head[p];i;i=e[i].next)
    {

        printf("try p=%d e[%d].v=%d time=%d\n",p,i,e[i].v,time);
        dfs(e[i].v,time+1,stop);
        if(flag == 1)
        {
            break;
        }
    }
    book[p] = 0;
    if(flag == 1)
    {
        if(dian[p].time == time)
        {
            dian[p].ans++;
            printf("lable dian[%d].ans = %d\n",p,dian[p].ans);
        }
        book[p] = 0;
        return ;
    }
}

int main()
{
    scanf("%d%d",&n,&m);

    for(int i=1;i<n;i++)
    {
        scanf("%d%d",&aa,&bb);
        addage(aa,bb);
    }

    for(int i=1;i<=n;i++)
    {
        scanf("%d",&dian[i].time);
    }

    for(int i=1;i<=m;i++)
    {
        int u,v;
        scanf("%d%d",&u,&v);
        dfs(u,0,v);
        flag = 0;
    }

    //printf("");
}

调试输出如下(调试输出中,enter 表示刚进入当前层dfs的状态,try 表示即将进去下一层时dfs状态,found表示当前已找到目标点,lable表示找到符合条件的点并进行标记。):

6 3
2 3
1 2 
1 4 
4 5 
4 6 
0 2 5 1 2 3 
1 5
enter p=1 time = 0 stop = 5 book=0 flag=0
try p=1 e[3].v=4 time=0
enter p=4 time = 1 stop = 5 book=0 flag=0
try p=4 e[5].v=6 time=1
enter p=6 time = 2 stop = 5 book=0 flag=0
try p=4 e[4].v=5 time=1
enter p=5 time = 2 stop = 5 book=0 flag=0
found p=5 time=2
lable dian[5].ans = 1
lable dian[4].ans = 1
lable dian[1].ans = 1
1 3
enter p=1 time = 0 stop = 3 book=0 flag=0
try p=1 e[3].v=4 time=0
enter p=4 time = 1 stop = 3 book=0 flag=0
try p=4 e[5].v=6 time=1
enter p=6 time = 2 stop = 3 book=0 flag=0
try p=4 e[4].v=5 time=1
enter p=5 time = 2 stop = 3 book=0 flag=0
try p=1 e[2].v=2 time=0
enter p=2 time = 1 stop = 3 book=0 flag=0
try p=2 e[1].v=3 time=1
enter p=3 time = 2 stop = 3 book=0 flag=0
found p=3 time=2
lable dian[1].ans = 2
2 6
enter p=2 time = 0 stop = 6 book=0 flag=0
try p=2 e[1].v=3 time=0
enter p=3 time = 1 stop = 6 book=0 flag=0

by 陈诺sb @ 2019-11-11 02:26:39

%%%


by Matrix_ @ 2019-11-11 16:47:30

发现问题了。。。其实就是链式前向星建图的时候忘了反向建了。。。。。。


|