7-15 球隊“食物鏈” 某國的足球聯賽中有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≤K≤N),滿足:a K <b K 且對於任意小於K的正整數i,a i =b i
。輸入格式:
輸入第一行給出一個整數N(2≤N≤20),爲參賽球隊數。隨後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
//注意:i戰勝j可以是st[i][j]='W'||st[j][i]='L';
#include<stdio.h>
#include<string.h>
int n;
char st[25][25];
int a[25];
int ans;
int l;
int visit[25];
int u;
void dfs(int v)
{
int i,j;
if(ans==1)
return ;
if(l==n)
{
if(st[v][u]=='W'||st[u][v]=='L')
{
for(j=0;j<n-1;j++)
printf("%d ",a[j]+1);
printf("%d\n",a[n-1]+1);
ans=1;
return ;
}
}
for(i=0;i<n;i++)
{
if(ans==1)
return ;
int tag=0;
//優化,因爲是一個環,若該點沒有戰勝0,則就沒有必要對該點判斷下去
for(j=1;j<n;j++)
{
if(!visit[j]&&st[j][0]=='W'||st[0][j]=='L')
{
tag=1;
break;
}
}
if(tag==0)
return ;
if(!visit[i]&&(st[v][i]=='W'||st[i][v]=='L'))
{
visit[i]=1;
a[l]=i;
l++;
dfs(i);
visit[i]=0;
l--;
}
}
}
int main()
{
int i,j;
scanf("%d",&n);
for(i=0;i<n;i++)
scanf("%s",st[i]);
int tag=0;
//優化,因爲是一個環,所以若存在一個食物鏈,就直接判斷從0開始是否可以即可
for(i=1;i<n;i++)
{
if(st[i][0]=='W'||st[0][i]=='L')
{
tag=1;
break;
}
}
if(tag==0)
{
printf("No Solution\n");
return 0;
}
memset(visit,0,sizeof(visit));
ans=0;
l=0;
u=0;
a[l]=0;
l++;
visit[0]=1;
dfs(0);
if(ans==0)
printf("No Solution\n");
return 0;
}