upc 8377: Playoff(搜索-dfs)

8377: Playoff

题目描述:

The Minato Mirai Football Association hosts its annual championship as a single round-robin tournament, in which each team plays a single match against all the others. Unlike many other round-robin tournaments of football, matches never result in a draw in this tournament. When the regular time match is a tie, overtime is played, and, when it is a tie again, a penalty shootout is played to decide the winner.

If two or more teams won the most number of matches in the round-robin, a playoff is conducted among them to decide the champion. However, if the number of teams is an odd number, it is possible that all the teams may have the same number of wins and losses, in which case all the teams participate in the playoff, called a "full playoff" here.

Now, some of the tournament matches have already been played and we know their results. Whether or not a full playoff will be required may depend on the results of the remaining matches. Write a program that computes the number of win/loss combination patterns of the remaining matches that lead to a full playoff.

The first datatset of the Sample Input represents the results of the first three matches in a round-robin tournament of five teams, shown in the following table. In the table, gray cells indicate the matches not played yet.

In this case, all the teams win the same number of matches with only two win/loss combination patterns of the remaining matches, which lead to a full playoff, as shown below. In the two tables, the differences are indicated in light yellow.


输入:

The input consists of multiple datasets, each in the following format.

n

m

x1 y1

...

xm ym

n is an odd integer, 3, 5, 7, or 9, indicating the number of teams participating in the tournament. m is a positive integer less than n(n−1)/2, which is the number of matches already finished. xi and yi give the result of the i-th match that has already taken place, indicating that team xi defeated team yi. Each of xi and yi is an integer 1 through n which indicates the team number. No team plays against itself, that is, for any i, xi ≠ yi. The match result of the same team pair appears at most once. That is, if i ≠ j, then (xi,yi) ≠ (xj,yj) and (xi,yi) ≠ (yj,xj) hold.

The end of the input is indicated by a line containing a zero. The number of datasets does not exceed 100.


输出:

For each dataset, output a single line containing one integer which indicates the number of possible future win/loss patterns that a full playoff will be required.


样例输入:

5

3

3 2

4 1

5 1


3

1

1 2


3

2

1 2

3 2


5

4

4 1

4 2

5 1

5 2


5

3

4 1

4 2

5 1


5

4

3 2

4 1

5 1

5 2


9

11

6 1

6 4

7 2

7 3

7 4

8 2

8 3

8 4

9 1

9 3

9 5


9

10

6 1

6 4

7 2

7 3

7 4

8 2

8 3

8 4

9 1

9 3


5

6

4 3

2 1

5 1

2 4

1 3

2 3


9

1

1 2

0


样例输出:

2

1

0

0

1

0

0

16

0

1615040

 

【小结】:

不做不发现,原来自己的代码实现能力都不足以让我写出一个DFS了。

现在都开学了,自己多抽出时间来练习好这个搜索的基本功。

(搜索,DP-(背包,数位Dp,概率Dp,树形Dp),并查集,数论,树状数组,线段树)

上面的都要我去学,我都不太会,要是停留在做贪心,那就不叫算法竞赛了。

【题意】:

其实这个题非常好读懂,就是因为它是英语题目,让我困惑了不少。

其实你看看上面给你的三幅图,了解一下我下面说的。

题目说:有很多支队伍进行比赛,然后题目想达到的效果是????

它说,每一支队伍我想要知道,它    输和赢的次数       全部队伍都一样。

问有多少种这样的情况。(n给了最大就是9,肯定是一个奇数)。

【题解】:

这个题目想要统一一下有多少种方案,不如我们看一看示例给我们的极端例子。

9

1

1 2

这个例子最多才1e6的数据量,这不就是引领这我们去写深搜吗???

其实写深搜真的有点生疏了,这次还是二维的状态来深搜。

后来想明白才知道,原来它不会回去的,只要写两个方向的所出现的状况。

宏观调控一下就差不多了。

关键是剪枝,不剪枝的话   :2^36的复杂度,

剪枝:

1、如果题目给定了一些已有的条件已经超过了半数比赛的话。直接输出答案。

2、如果题目中不能走的情况,一定要标注好走两条路的情况。

 

贴上代码:

参考passer_by:https://blog.csdn.net/passer__/article/details/81987146

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N=10;
int Lost[N],Win[N],vis[N][N];
int n,m,K,ans;
void dfs(int x,int y){
    if(y==n+1){
        x++;
        y=1+x;
    }
    //printf("X: %d , Y: %d\n",x,y);
    if(x==n){
        ans++;
        return ;
    }
    if(vis[x][y]==0){

        if(Win[x]<K&&Lost[y]<K){
            Win[x]++;
            Lost[y]++;
            dfs(x,y+1);
            Win[x]--;
            Lost[y]--;
        }
        if(Win[y]<K&&Lost[x]<K){
            Win[y]++;
            Lost[x]++;
            dfs(x,y+1);
            Win[y]--;
            Lost[x]--;
        }
    }else{
        dfs(x,y+1);
    }

}
void solve(){
    memset(vis,0,sizeof(vis));
    memset(Lost,0,sizeof(Lost));
    memset(Win,0,sizeof(Win));
    scanf("%d",&m);
    int x,y;
    int flag=0;
    K=(n-1)/2;
    //printf("%d\n",K);
    for(int i=1;i<=m;i++){
        scanf("%d%d",&x,&y);
        vis[x][y]=vis[y][x]=1;
        Win[x]++;
        Lost[y]++;
        if(Win[x]>K||Lost[y]>K){
            flag=1;
        }
    }
    if(flag){
        printf("0\n");
    }else{
        ans=0;
        dfs(1,2);
        printf("%d\n",ans);
    }
    return ;
}
int main()
{
    while(~scanf("%d",&n),n){
        solve();
    }
    return 0;
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值