[dfs剪枝]球队“食物链”

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

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

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

注:排列{ a1​​ a2​​ ⋯ aN​​}在字典序上小于排列{ b1​​ b2​​ ⋯ bN​​ },当且仅当存在整数K(1),满足:aK​​<bK​​且对于任意小于K的正整数i,ai​​=bi​​。

输入格式:

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

输出格式:

按题目要求找到“食物链”T1​​ T2​​ ⋯ TN​​,将这N个数依次输出在一行上,数字间以1个空格分隔,行的首尾不得有多余空格。若不存在“食物链”,输出“No Solution”。

输入样例1:

5
-LWDW
W-LDW
WW-LW
DWW-W
DDLW-

输出样例1:

1 3 5 4 2

输入样例2:

5
-WDDW
D-DWL
DD-DW
DDW-D
DDDD-

输出样例2:

No Solution

以1作为食物链的开头
#include <iostream>
#include<cstdio>
#include<cstring>
using namespace std;

int n;
char Map[25][25];
int tmp[25],vis[25];

inline bool dfs(int x,int u){
  tmp[x]=u;
  if(x==n){
    if(Map[u][1]=='W'||Map[1][u]=='L') return 1;
    else return 0;
  }

  /*剪枝*/
  int flag=0;
  for(int i=1;i<=n;i++){
    if(!vis[i]&&(Map[i][1]=='W'||Map[1][i]=='L')){
        flag=1;break;
    }
  }
  if(!flag) return 0;

  vis[u]=1;
  for(int i=1;i<=n;i++){
    if(!vis[i]&&(Map[u][i]=='W'||Map[i][u]=='L')) {
        if(dfs(x+1,i)) return 1;
    }
  }
  vis[u]=0;
  return 0;
}

int main()
{
    scanf("%d",&n);
    for(int i=1;i<=n;i++){
        for(int j=1;j<=n;j++){
            scanf(" %c",&Map[i][j]);
        }
    }
    if(dfs(1,1)){
        for(int i=1;i<=n;i++){
            if(i!=1) printf(" ");
            printf("%d",tmp[i]);
        }
    }
    else puts("No Solution");
    return 0;
}
View Code

猜你喜欢

转载自www.cnblogs.com/lllxq/p/10542171.html