UVa 572 Oil Deposits + PAT 1003 Emergency 两道DFS题

1.UVa 572紫书题目,作为熟悉DFS之用

//dfs uva572
const int maxn = 100 + 5;

char pic[maxn][maxn];
int m,n,idx[maxn][maxn];

void dfs(int r,int c,int id){
    if(r<0||r>=m||c<0||c>=n) return; //出界的格子
    if(idx[r][c]>0||pic[r][c]!='@') return; //不是@或已经访问过
    idx[r][c] = id; //联通分量编号
    for(int dr = -1;dr<=1;dr++)
        for(int dc=-1;dc<=1;dc++)
        if(dr!=0||dc!=0) dfs(r+dr,c+dc,id);//只要不是原地不动
}

int main(){
    while(scanf("%d%d",&m,&n)==2&&m&&n){
        for(int i=0;i<m;i++) scanf("%s",pic[i]);
        memset(idx,0,sizeof(idx));
        int cnt = 0;
        for(int i=0;i<m;i++)
            for(int j=0;j<n;j++)
            if(idx[i][j]==0&&pic[i][j]=='@') dfs(i,j,++cnt);
        printf("%d\n",cnt);
    }

    return 0;
}

2.PAT 1003 emergency
其实是最短路题,但是用DFS可以做,在DFS的代码上改动一下即可。
花了好多时间做这个题,对DFS掌握的还是不够熟练啊,对一些枝上的细节处理不够好,一直通过部分案例。好在最后终于改好了。
其实有个小问题,这个DFS是存在环的,比如从0→1→0→2,在进入DFS前把起始点访问就好了,但是不用这么做也可以,因为求最短路,这种重复计算的路径肯定是会被排除在外的。

//1003 DFS改动

int n,c1,c2,a[505],path[505][505],vis[505];
int cnt,mincost,cost,maxteams,teams;

void DFS(int i){
    //printf("当前点%d 路径长度%d 最短路径数%d\n",i,cost,cnt);
    if(i == c2)
    {
        if(cost<mincost) {
            //printf("新的最短路%d\n",cost);
            cnt=1;
            mincost = cost;
            maxteams = teams;
        }
        else if(cost==mincost) {
            //printf("重复的最短路径%d\n",cost);
            cnt++;
            if(teams>maxteams)
                maxteams = teams;
        }
        return;
    }
    if(cost>mincost) return;//如果没到目标但是已经花费比之前的最短大了,就剪掉
    int j;
    for(j = 0; j < n; j++){
        if(path[i][j] != -1 && !vis[j]){
            cost+=path[i][j];
            teams += a[j];
            vis[j] = 1;

            DFS(j);

            vis[j]=0;
            cost -= path[i][j];
            teams -= a[j];
        }
    }
}

int main(){
    int m,loc1,loc2,w;
    while(scanf("%d%d%d%d",&n,&m,&c1,&c2)!=EOF){
        for(int i=0;i<n;i++) scanf("%d",&a[i]);
        memset(path,-1,sizeof(path));
        memset(vis,0,sizeof(vis));

        for(int i=0;i<m;i++){
            scanf("%d%d%d",&loc1,&loc2,&w);
            path[loc1][loc2] = path[loc2][loc1] = w;
        }
        mincost = INT_MAX;
        cnt = 0;
        teams = a[c1];
        cost = 0;
        //vis[c1]=1;
        DFS(c1);
        printf("%d %d\n",cnt,maxteams);
    }
    return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值