pku 2531 Network Saboteur DFS

http://poj.org/problem?id=2531

就是和原来的奶牛翻碗问题,翻黑白棋问题,开门问题属于一类题目,对于每一点只有两种状态,要么属于A要么属于DFS枚举出所有的状态即可。。才开始自己按自己的习惯写的DFS1469ms

最后看了看别人的优化到了375ms。。。就是在处理求和时的优化了。。

我的代码:

View Code
#include <iostream>

#include <cstring>

#include <cstdio>

#define maxn 23

using namespace std;



bool vt[maxn];

int n,ans;

int map[maxn][maxn];



void dfs(int num)

{

    int i,j;

    if (num == n)

    {

        int sum = 0;

        for (i = 0; i < n; ++i)

        {

            if (vt[i])

            {

                for (j = 0; j < n; ++j)

                {

                    if (!vt[j])

                    sum += map[i][j];

                }

            }

        }

        if (sum > ans) ans = sum;

        return ;

    }

    for (int k = 0; k < 2; ++k)

    {

        if (k == 1)//代表属于A

        {

            vt[num + 1] = true;

            dfs(num + 1);

            vt[num + 1] = false;

        }

        else if (k == 0)//代表不属于A

        {

            dfs(num + 1);

        }

    }

}

int main()

{

    //freopen("in.txt","r",stdin);

    int i,j;

    scanf("%d",&n);

    for (i = 0; i < n; ++i)

    {

        for (j = 0; j < n; ++j)

        {

            scanf("%d",&map[i][j]);

        }

    }

    ans = -99999999;

    memset(vt,false,sizeof(vt));

    for (i = 0; i < 2; ++i)

    {

        if (i == 1)

        {

            vt[0] = true;

            dfs(1);

            vt[0] = false;

        }

        else if (i == 0)

        {

            dfs(1);

        }

    }

    printf("%d\n",ans);

    return 0;

}

优化后代码:

View Code
#include <iostream>

#include <cstring>

#include <cstdio>

#define maxn 24

using namespace std;



bool vt[maxn];

int map[maxn][maxn];

int n,ans;



void dfs(int num,int sum)

{

    int i;

    if (num == n)

    {

        if (sum > ans) ans = sum;

        return ;

    }

    vt[num] = false;

    int m = 0;

    //每次当这个点不属于A要加上他与属于A的距离

    for (i = 0; i <= num; ++i)

    {

        if (vt[i]) m += map[num][i];

    }

    dfs(num + 1,sum + m);



    vt[num] = true;

     m = 0;

    //每次当这个点属于A要加上他与不属于A的距离

    for (i = 0; i <= num; ++i)

    {

        if (!vt[i])  m += map[num][i];

    }

    dfs(num + 1,sum +m);

}

int main()

{

    //freopen("in.txt","r",stdin);

    int i,j;

    scanf("%d",&n);

    for (i = 0; i < n; ++i)

    {

        for (j = 0; j < n; ++j)

        {

            scanf("%d",&map[i][j]);

        }

    }

    ans = -9999999;

    memset(vt,false,sizeof(vt));

    dfs(0,0);

    printf("%d\n",ans);

    return 0;

}

你可能感兴趣的:(NetWork)