7-15 球隊“食物鏈” (30 分)


某國的足球聯賽中有 N支參賽球隊,編號從1至N。聯賽采用主客場雙循環賽制,參賽球隊兩兩之間在雙方主場各賽一場。

聯賽戰罷,結果已經塵埃落定。此時,聯賽主席突發奇想,希望從中找出一條包含所有球隊的“食物鏈”,來說明聯賽的精彩程度。“食物鏈”為一個1至N的排列{ T1​​ T2​​ ⋯ TN​​ },滿足:球隊T1​​戰勝過球隊T2​​,球隊T2​​戰勝過球隊T3​​,⋯,球隊T(N1)​​戰勝過球隊TN​​,球隊TN​​戰勝過球隊T1​​。

現在主席請你從聯賽結果中找出“食物鏈”。若存在多條“食物鏈”,請找出字典序最小的。

注:排列{ a1​​ a2​​ ⋯ aN​​}在字典序上小於排列{ b1​​ b2​​⋯ bN​​ },當且僅當存在整數K(1KN),滿足:aK​​<bK​​且對於任意小於K的正整數i,ai​​=bi​​。

輸入格式:

輸入第一行給出一個整數N(2N20),為參賽球隊數。隨后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"

 

題意:輸出一條包含所有隊伍且去重的最小字典序的球隊T(N1)​​戰勝過球隊TN​​,球隊TN​​戰勝過球隊T1的集合,輸入時'W'表示i(行)隊贏了j(列)隊,'L'表示j(列)隊贏了i(行)隊,若找的到則輸出,否則輸出“No Solution”。

注意:1,
此題要求“食物鏈”包含所有球隊,因此此鏈長度為n。

          2,此題要求“食物鏈”輸出字典序最小的,而搜索按升序搜索,因此只需輸出第一個即可滿足最小字典序的條件
          3,判斷下一步是否能走,若不能則返回,若不加這步會超時
          4,標記用一維數組是因為每支隊伍在鏈中有且只有出現一次
          5,注意這里可能要建立雙向邊

 

 1 #include<iostream>
 2 #include<cstdio>
 3 #include<cstring>
 4 using namespace std;
 5 const int amn=1e2+5;
 6 int a[amn][amn],mp[amn],ans[amn];
 7 char in[amn];
 8 int n,f=0;
 9 void s(int i,int len)
10 {
11     if(f)return;
12     ans[len]=i;
13     if(len==n)///此題要求“食物鏈”包含所有球隊,因此此鏈長度為n
14     {
15         if(a[i][1])///此題要求“食物鏈”輸出字典序最小的,而搜索按升序搜索,因此只需輸出第一個即可滿足最小字典序的條件
16             f=1;
17         return;
18     }
19     ///判斷下一步是否能走,若不能則返回,若不加這步會超時
20     int cn=0;
21     for(int p=1; p<=n; p++)
22     {
23         if(mp[p]==0&&a[p][1]==1)
24             cn=1;
25     }
26     if(cn==0) return;
27     for(int k=1; k<=n; k++)
28     {
29         ///如果當前存在下一步且下一步能走,則繼續搜索
30         if(a[i][k]==1&&mp[k]==0)mp[i]=1,s(k,len+1),mp[i]=0;///標記當前節點,回溯后清除標記,標記用一維數組是因為每支隊伍在鏈中有且只有出現一次
31     }
32 }
33 int main()
34 {
35 
36     while(cin>>n)
37     {
38         memset(a,0,sizeof(a));
39         for(int i=1; i<=n; i++)
40         {
41             ans[i]=amn;
42             mp[i]=0;
43             scanf("%s",in+1);
44             for(int j=1; j<=n; j++)
45             {
46                 if(in[j]=='W')a[i][j]=1;///注意這里可能要建立雙向邊
47                 if(in[j]=='L')a[j][i]=1;
48             }
49         }
50         f=0;
51         s(1,1);
52         if(f)
53         {
54             for(int i=1; i<=n; i++)
55             {
56                 cout<<ans[i];
57                 if(i<n)cout<<" ";
58                 else cout<<endl;
59             }
60         }
61         else
62         {
63             cout<<"No Solution\n";
64         }
65 
66     }
67 }

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM