PTA 5-15 球队“食物链” (2017cccc初赛L3-3)

来源:互联网 发布:手机影视剪辑软件 编辑:程序博客网 时间:2024/06/05 05:59

5-15 球队“食物链”   (30分)

某国的足球联赛中有NN支参赛球队,编号从1至NN。联赛采用主客场双循环赛制,参赛球队两两之间在双方主场各赛一场。

联赛战罢,结果已经尘埃落定。此时,联赛主席突发奇想,希望从中找出一条包含所有球队的“食物链”,来说明联赛的精彩程度。“食物链”为一个1至NN的排列{ T_1T1 T_2T2 \cdots T_NTN },满足:球队T_1T1战胜过球队T_2T2,球队T_2T2战胜过球队T_3T3\cdots,球队T_{(N-1)}T(N1)战胜过球队T_NTN,球队T_NTN战胜过球队T_1T1

现在主席请你从联赛结果中找出“食物链”。若存在多条“食物链”,请找出字典序最小的。

注:排列{ a_1a1 a_2a2 \cdots a_NaN}在字典序上小于排列{ b_1b1 b_2b2 \cdots b_NbN },当且仅当存在整数KK1 \le K \le N1KN),满足:a_K < b_KaK<bK且对于任意小于KK的正整数iia_i=b_iai=bi

输入格式:

输入第一行给出一个整数NN2 \le N \le 202N20),为参赛球队数。随后NN行,每行NN个字符,给出了N\times NN×N的联赛结果表,其中第ii行第jj列的字符为球队ii在主场对阵球队jj的比赛结果:W表示球队ii战胜球队jjL表示球队ii负于球队jjD表示两队打平,-表示无效(当i=ji=j时)。输入中无多余空格。

输出格式:

按题目要求找到“食物链”T_1T1 T_2T2 \cdots T_NTN,将这NN个数依次输出在一行上,数字间以1个空格分隔,行的首尾不得有多余空格。若不存在“食物链”,输出“No Solution”。

输入样例1:

5-LWDWW-LDWWW-LWDWW-WDDLW-

输出样例1:

1 3 5 4 2

输入样例2:

5-WDDWD-DWLDD-DWDDW-DDDDD-

输出样例2:

No Solution
提示

题意:

略。

思路:

剪枝思路来源:http://www.liuchuo.net/

我们可以这样建图:

字符为'W'的建从i(当前行号)到j(当前列号)的边,字符为'L'的建从j(当前行号)到i(当前列号)的边,用dfs从1节点遍历+回溯去求哈密顿回路。

剪枝条件:dfs到某个子序列时,如果当前未访问节点无法与1节点构成回路,就不往下搜索。

示例程序

#include <cstdio>#include <cstring>using namespace std;int mp[20][20],a[20],v[20],n,flag=0;void dfs(int t,int deep){    int i;    if(flag==1)    {        return;    }    a[deep]=t;    if(deep==n-1)    {        if(mp[t][0]==1)        {            flag=1;        }        return;    }    for(i=1;n>i;i++)//剪枝    {        if(v[i]==0&&mp[i][0]==1)        {            break;        }    }    if(n==i)//无法构成回路,停止搜索    {        return;    }    for(i=1;n>i;i++)    {        if(v[i]==0&&mp[t][i]==1)        {            v[i]=1;            dfs(i,deep+1);            v[i]=0;        }    }}int main(){    int i,i1;    char s[21];    scanf("%d",&n);    memset(mp,0,sizeof(mp));    memset(v,0,sizeof(v));    for(i=0;n>i;i++)    {        scanf("%s",s);        for(i1=0;s[i1]!='\0';i1++)        {            if(s[i1]=='W')//建图            {                mp[i][i1]=1;            }            else if(s[i1]=='L')            {                mp[i1][i]=1;            }        }    }    v[0]=1;    dfs(0,0);    if(flag==1)    {        for(i=0;n>i;i++)        {            if(i==0)            {                printf("%d",a[i]+1);            }            else            {                printf(" %d",a[i]+1);            }        }    }    else    {        printf("No Solution");    }    return 0;}


0 0