球队“食物链”(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?(N−1)??战胜过球队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剪枝与优化+状态压缩+代码技巧+好题)