zoukankan      html  css  js  c++  java
  • 7-15 球队“食物链”天梯训练2

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

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

    输入格式:

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

    输出格式:

    按题目要求找到“食物链”T​1T2 ⋯ 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

    直接DFS会T,所以进行剪枝,只需要在当前找下一个节点的时候,先找一下,剩下没有用上的球队,有没有能赢过第一支球队的,如果没有,那么就不需要继续往下找了

    #include<iostream>
    #include<stdio.h>
    #include<cmath>
    #include<float.h>
    #include<string.h>
    #include<algorithm>
    #include<queue>
    #include<stack>
    #include<vector>
    #include<list>
    #define sf scanf
    #define pf printf
    #define scf(x) scanf("%d",&x)
    #define scff(x,y) scanf("%d%d",&x,&y)
    #define scfff(x,y,z) scanf("%d%d%d",&x,&y,&z)
    #define prf(x) printf("%d
    ",x)
    #define mm(x,b) memset((x),(b),sizeof(x))
    #define rep(i,a,n) for (int i=a;i<n;i++)
    #define per(i,a,n) for (int i=a;i>=n;i--)
    #define de(x) cout<<#x<<"="<<x<<","
    #define all(x) x.begin(),x.end()
    #define dee(x) cout<<#x<<"="<<x<<"
    "
    #define fi first
    #define se second
    #define pii pair<int,int>
    #define mp make_pair
    typedef long long ll;
    const ll mod=1e9+7;
    const double eps=1e-8;
    const int inf=0x3f3f3f3f;
    using namespace std;
    const double pi=acos(-1.0);
    const int N=1e4+10;
    char a[25][25],s[25][25];
    int used[25];
    list<int> v;
    int n;
    bool dfs(int x)
    {
    	if(v.size()==n)
    	{
    		if(a[v.back()][v.front() ]=='W')
    		return true;
    		return false;
    	}
    	int temp=0;
    	rep(i,1,n+1)//判断是否要剪枝
    	{
    		if(used[i]==1&&a[i][v.front()]=='W') 
    		temp=1;
    	}
    	if(temp==0) return false;
    	rep(i,1,n+1)
    	{
    		if(a[x][i]=='W'&&used[i]==1)
    		{
    			used[i]=0;
    			v.push_back(i);
    			if(dfs(i))
    			return true;
    			v.pop_back();
    			used[i]=1;
    		}
    	}
    	return false;
    }
    int main()
    {
    	
    	scf(n);
    	rep(i,1,n+1)	
    	sf("%s",s[i]+1);
    	mm(a,'L');
    	rep(i,1,n+1)
    	{
    		rep(j,1,n+1)
    		{
    			if(s[i][j]=='W')
    				a[i][j]='W';
    			else if(s[i][j]=='L')
    				a[j][i]='W';
    		}
    	}
    	rep(i,1,n+1)
    	{
    		v.clear();
    		rep(j,1,n+1) used[j]=1;
    		used[i]=0;
    		v.push_back(i); 
    		if(dfs(i))
    		{
    			rep(i,0,n)
    			{
    				if(i==0)
    				cout<<v.front();
    				else
    				cout<<" "<<v.front();
    				v.pop_front();
    			}
    			return 0;
    		}
    	}
    	cout<<"No Solution";
    	return 0;
    }
    
    
  • 相关阅读:
    LOJ2565. 「SDOI2018」旧试题
    位运算
    Arrays.sort()原理
    LinkedList源码解析
    二维数组排序
    数据结构和算法-五大常用算法:贪心算法
    数据结构和算法-五大常用算法:分支限界法
    数据结构和算法-五大常用算法:分治算法
    数据结构和算法-二分查找
    Arrays.copyOf()&Arrays.copyOfRange()&System.arraycopy
  • 原文地址:https://www.cnblogs.com/wzl19981116/p/10485523.html
Copyright © 2011-2022 走看看