浏览器标题切换
浏览器标题切换end

ACM - 图论 - 模板 - 持续更新

PS

希望今年的CCPC拿个好名次!!!

三个诸葛亮加油!!!给我冲!!!

邻接表

int tot,head[N];

struct node
{
    int v,w,nex; //w权值
    // 根据题意加 花费 cost
}e[M];

void add(int u,int v,int w)
{
    e[++tot].v=v;
    e[tot].w=w;
    e[tot].nex=head[u];
    head[u]=tot;
   // e[tot].cost=cost;  根据题意加
}

int main()
{
    tot=-1;
    mem(head,-1);
    return 0;
}

DFS

一般搜索,搜连通块等:定义void dfs(),需要book数组进行标记,搜索过后不需要取消标记;如果是给的图是char型,那么不需要开book数组,直接把搜过的字符直接变成图中没有出现过的字符,其实间接相当于标记,但是省了一点空间。
典型例题:POJ2386(AC代码在下面);Aizu0118

一般搜索,搜路径条数的时候:需要在方向遍历的里面的if里面进行 book的标记 + DFS + 取消标记;
典型例题 ZOJ2110 + 奇偶剪枝 HDU1010;
HDU1010题意(给出起点、终点、T,问小狗从起点走到终点能否恰好为T秒。这题限定了步数,(未必是bfs啊),利用奇偶剪枝才不会超时;没有进行搜索的时候先判断全局T-[abs(ex-sx)+abs(ey-sy)]结果为非偶数(奇数),则无法在t步恰好到达;搜索的时候T-step-[abs(ex-sx)+abs(ey-sy)]进行判断;当该值小于零或者是奇数的时候就可以return了。(不要忘了小于零)),具体代码去VJ上看之前写过的。

记忆化搜索的话:定义int dfs() 函数,并且不需要标记,book数组只用于记录次数/步数等,一旦搜到走过的book[x][y],就直接返回,不用再往下搜索,其实就是有部分的动态规划的思想在;
典型例题:https://www.cnblogs.com/OFSHK/p/13669715.html

POJ2386 DFS和BFS都可以 求‘W’的连通块数目。 下面是AC代码:

#include<iostream>
#include<string.h>
#include<algorithm>
#include<stdio.h>
#include<cmath>
#include<list>
#include<stdlib.h>
#include<map>
#include<vector>
#include<stack>
#include<stdio.h>
#include<queue>
using namespace std;
typedef long long ll;
#define sc(T) scanf("%d",&T)
#define scc(x,y) scanf("%d %d",&x,&y)
#define pr(T) printf("%d\n",T)
#define f(a,b,c) for (int a=b;a<c;a++)
#define ff(a,b,c) for (int a=b;a>c;a--)
#define inf 0x3f3f3f3f
#define mem(a,b) memset(a,b,sizeof(a))
#define eps 1e-9
#define PI acos(-1)

char s[110][110];
int n,m,ans=0;
int to[8][2]= {{0,-1},{0,1},{-1,0},{1,0},{-1,1},{1,1},{-1,-1},{1,-1}};
bool book[110][110];

void dfs(int x,int y)
{
    book[x][y]=1; // 在这里标记 不是if内
    f(i,0,8)
    {
        int tx=x+to[i][0];
        int ty=y+to[i][1];
        if(tx>=0&&tx<n&&ty>=0&&ty<m&&!book[tx][ty]&&s[tx][ty]=='W')
        {
            //不标记的话改s,s[tx][ty]='.'
//            book[tx][ty]=1;
//            ans++;
            dfs(tx,ty);
//            book[tx][ty]=0;
        }
    }
}

int main()
{
    scc(n,m);
    f(i,0,n)
    scanf("%s",s[i]);
    for(int i=0; i<n; i++)
    {
        for(int j=0; j<m; j++)
        {
//            if(s[i][j]=='W')
//                dfs(i,j);
            if(s[i][j]=='W'&&!book[i][j])
                ans++,dfs(i,j);
        }
    }
    pr(ans);
    return 0;
}

BFS

没啥特别的,就爆搜,求最短XXX。
直接敲就行。

posted @ 2020-10-05 20:17  抓水母的派大星  阅读(124)  评论(0编辑  收藏  举报