PAT-L3-球队“食物链”-dfs-状压-set

题目分析:

1. 一场双循环赛制的篮球赛,注意双循环,双循环!

2. 共有n只球队,两两之间有胜有负有平局;

3. 输入:

    举例:

    第一行:W:代表球队1打赢这只队伍

                  L:代表球队2没打赢这只队伍

    因为两队伍有两场比赛,所以互相都可能打败对方;

    如果A队打赢过B队,就连一条A到B的有向边;

    建边时注意,如果A队 "L" B队,就连一条B->A边;(忘了这个wa了一发)

    (这是坑点1,不是最可怕的)

4. 目的:

    找到一条食物链:1 3 5 4 2;

    代表:1赢过3,3赢过5,5赢过4,4赢过2,并且 2赢过1

    要循环的;

解题思路:


1. 很明显dfs可以解决;如果A队打赢过B队,就连一条A到B的有向边;

    (因为我很傻以为球队有很多只,怕超时,sb的用set写,其实这个二维数组建边就行了,不过两种写法差别不大,我就当作 是温习一下set的知识。结果被set一个坑点卡了一晚上,贼气,我在结尾说这个蛋疼的故事)

2. 减枝:状压一下吧(应该是叫状压吧?唉,我太菜了)

    state[cur][i]表示状态cur的最后一步是i;

    如果为1,代表这个不可行,continue掉;

题目链接:点击打开题目链接

AC代码如下:

#include<bits/stdc++.h>
#define test printf("***\n")
#define ka getchar();getchar()
#define ka1 getchar()
#define iis std::ios::sync_with_stdio(false)
using namespace std;
typedef long long LL;
const int N = 110;
const int M = 1000005;
const int INF = 0x3f3f3f3f;
const LL mod = 1000000007;
const double eps=1e-8;
int vis[N],ans[N];
int state[1<<21][N];//坑点1,状压处理
set<int> son[N];
char ar[N][N];
int flag,n;
void dfs(int u,int t,int cur){
    if(flag)return;
    for(set<int>::iterator p=son[u].begin();p!=son[u].end();++p){
        int tmp=*p;
        if(t==n){
            if(tmp==ans[0]){
                flag=1;
                return;
            }
            continue;
        }
        if(vis[tmp]||state[cur|(1<<tmp)][tmp])continue;
        vis[tmp]=1;
        ans[t]=tmp;
        dfs(tmp,t+1,cur|(1<<tmp));
        if(flag)return;
        state[cur|(1<<tmp)][tmp]=1;
        vis[tmp]=0;
    }
}
int main(){
    flag=0;
    scanf("%d",&n);
    for(int i=0;i<=n;++i){
        son[i].clear();
    }
    for(int i=0;i<n;++i){
        scanf("%s",ar[i]);
        for(int j=0;j<n;++j){
            if(ar[i][j]=='W'){
                son[i].insert(j);
            }
            if(ar[i][j]=='L'){
                son[j].insert(i);//坑点2,双循环赛制
            }
        }
    }
    memset(vis,0,sizeof(vis));
    vis[0]=1;
    ans[0]=0;
    dfs(0,1,1);
    if(flag==0){
        printf("No Solution\n");
        return 0;
    }
    for(int i=0;i<n;++i){
        if(i!=n-1) printf("%d ",ans[i]+1);
        else printf("%d\n",ans[i]+1);
    }
    return 0;
}

map

(set遍历元素不是要先:set<int>::iterator 吗;然后我 set<int>::iterator p,把p作为全局变量,然后dfs找bug找一晚上,至于为什么不要设为全局变量,自己试一下就知道了)

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值