球队“食物链”(DFS+剪枝)

Posted jiamian

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了球队“食物链”(DFS+剪枝)相关的知识,希望对你有一定的参考价值。

 

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

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

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

注:排列{ a?1?? a?2?? a?N??}在字典序上小于排列{ b?1?? b?2?? b?N?? },当且仅当存在整数K(1),满足:a?K??<b?K??且对于任意小于K的正整数i,a?i??=b?i??。

输入格式:

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

输出格式:

按题目要求找到“食物链”T?1?? T?2?? T?N??,将这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 <stdio.h>
 2 #include <iostream>
 3 #include <string>
 4 #include <string.h>
 5 #include <algorithm>
 6 #include <map>
 7 #include <vector>
 8 #include <set>
 9 #include <stack>
10 #include <queue>
11 #include <math.h>
12 #include <sstream>
13 using namespace std;
14 typedef long long LL;
15 const int INF=0x3f3f3f3f;
16 const int maxn=1e5+10;
17 const double eps =1e-8;
18 
19 int n;
20 char G[105][105];
21 int win[105][105];
22 int vis[105];
23 int flag;
24 int ans[105];
25 
26 void DFS(int num,int step)
27 {
28     if(flag==1) return;
29     ans[step]=num; 
30     if(step==n)
31     {
32         if(win[num][1]==1) flag=1;
33         return ;
34     }
35     
36     int ok=0;
37     for(int k=1;k<=n;k++)//优化点,如果剩下的点没有和起点相连的,就直接返回
38     {
39         if(!vis[k]&&win[k][1]==1)
40         {
41             ok=1; break;
42         }
43     }
44     if(ok==0) return ;
45     
46     for(int i=1;i<=n;i++)
47     {
48         if(vis[i]==0&&win[num][i]==1)
49         {
50             vis[i]=1;
51         //    ans[step+1]=i;
52             DFS(i,step+1);
53         //    if(flag==1) return ;
54             vis[i]=0;
55         }
56     }
57 }
58 
59 int main()
60 {
61     #ifdef DEBUG 
62     freopen("sample.txt","r",stdin);
63     #endif
64     
65     scanf("%d",&n);
66     for(int i=1;i<=n;i++)
67         scanf("%s",G[i]+1);
68     for(int i=1;i<=n;i++)
69     {
70         for(int j=1;j<=n;j++)
71         {
72             if(G[i][j]==W) win[i][j]=1;
73             if(G[j][i]==L) win[i][j]=1; //别忘了 
74         }
75     }
76     vis[1]=1;
77     ans[1]=1;//如果能成功,起点必为1
78     DFS(1,1);
79     if(flag==0) printf("No Solution
");
80     else
81     {
82         for(int i=1;i<=n;i++)
83             printf(i==n?"%d
":"%d ",ans[i]);    
84     }
85     
86     return 0;
87 }

 

 

 

 

 

-

以上是关于球队“食物链”(DFS+剪枝)的主要内容,如果未能解决你的问题,请参考以下文章

[dfs] aw166. 数独(dfs剪枝与优化+状态压缩+代码技巧+好题)

HDU1010-奇偶剪枝(DFS)

出界的路径数--dfs记忆化+剪枝

Sicily 1153: 马的周游问题(DFS+剪枝)

DFS+剪枝Aw842.排列数 & Aw843.N-皇后问题

小木棒HDU1455(DFS+剪枝)