earthcup(竞赛图定理)

EarthCup

Time Limit: 2000/1000 MS (Java/Others)
Memory Limit: 131072/131072 K (Java/Others)

Problem Description

In the year of 2045,the soccer championship is gradually replaced by Earth Super Soccer Cup(We will call it EarthCup for short later).

For one EarthCup,there are n(n≤50000) soccer teams participated in. Every two teams will have a game. It means that every team will have n−1 games with all the other teams.

In order to make the result clear, it is ruled that if the two teams of a game have the same score when the game ends.Penalty shootout will last until there is a result.

In the EarthCup,every team has a Mark,and will score one point after winning a game and zero after losing a game. The team with the highest mark will be the champion.

In the year of 2333, somebody found that some teams had hired hackers to attack and modified the data of the EarthCup for many years.Maybe because of the great amount of the teams, this serious cheating behavior has not been found during hundreds of years.

To check whether the data was modified, they started to check the “Mark Table” in the past.

But because of the long ages, there were only the final Mark of each team reserved. No one remember the exact result of each game.Now they want to find out some “Mark Table” that must have been modified.

“Must have been modified” means we can not get this “Mark Table” by any exact result of each game according to the rules was given by.

Input

There is an positive integer T(T≤50) standing for the number of testcases.
For each testcase, there is an positive integer n standing for the number of teams participate in EarthCup.
The followed n lines describe the “Mark table”. The ith integer ai(0≤ai

Hint:

For the first testcase:
One possible way is:
Team1 won Team2 and Team3,gained 2 marks.Team2 won Team3 but lost the game with Team1,gained 1 mark.Team3 lost both games and gained 0.

For the second testcase:
It’s obviously impossible that all the teams would win all the games.So it must have been modified.
The Input ai is disordered.

Output
For each testcase, output “The data have been tampered with!”(without quotation) if it must have been modified,otherwise output “It seems to have no problem.”(without quotation).

Sample Input
2
3
2
1
0
3
2
2
2
Sample Output
It seems to have no problem.
The data have been tampered with!

题目大意:n个队,两两比赛,给出每个队的胜场,询问是否合法。








<script type="math/tex" id="MathJax-Element-28"> </script>

解:

这道题有一个现成的结论:here
然而我们可以用hall定理的思想。
这似乎是官方题解:
首先,我们检验一下所有队伍的积分的总和是否等于n ∗ (n − 1)/2,因为显然每场比赛有一个队伍获胜,
积分总和应该等于比赛场数。
如果积分的总和不对,就说明一定被修改过,否则继续进行判断。
我们先来考虑数据范围是n ≤ 100时的解法。我们可以建立一个网络流的模型:
对于每场比赛建立一个点,每支球队也建立一个点,S为源点,T为汇点:
1. 从S到每场比赛连一条容量为1的边
2. 每场比赛分别向它对应的两支球队各连一条容量为1的边
3. 第i支球队向T连一条容量为a (第i支球队的积分)的边
假如求一次最大流,这个模型满流了,即总流量为n ∗ (n − 1)/2,那么就存在至少一种能够满足积分数据
的比赛胜负情况,否则数据一定被修改过。 直观理解就是每场比赛有1个积分,这个积分要么分给参加这个
比赛中的一支队伍,要么给另一支。
利用最大流合理分配每场比赛的胜利(就是每个积分)给球队,使每支队伍的最终积分符合给出的积分数据。
现在我们对这个模型做一点改动,我们把第i支队伍拆成a 个点,拆出来的每个点向T连一条容量为1的边,
然后每场比赛向它对应的两支球队的所有拆出来的点都连一条容量为1的边。
在新的模型下,依然是可以满流时有合法方案。
现在的模型是一个二分图匹配模型,左右两部分点的个数相同,我们可以利用霍尔定理来判断能否有符合 条件的匹配方案。
应用在这道题中霍尔定理的简单描述就是,对于二分图左边的任意k个点,检查右边与他们直接相连的点的
个数是否大于等于k。详细的解释和证明可以在网上搜索。 对于这道题的模型,我们就可以把所有队伍按
积分排序,检查所有积分前k小的的队伍积分总和是否大于等于k ∗ (k − 1)/2,假如检查k从1 → n一直都
一直符合这个关系那么有合法方案,否则数据是一定被修改过的。
k ∗ (k − 1)/2是k支队伍之间所有比赛的场数,即对应这k支队伍之间表示比赛的结点的个数,这些结点
只与这k支队伍对应的结点相连。 k支队伍的积分总和就相当于k支球队对应的结点的个数的总和。

code(hdu真tm坑):

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;

int T,n;
long long s[50005];

int main()
{
    scanf("%d",&T);
    while(T--){
        scanf("%d",&n);
        long long num=0,vis=0;
        for(int i=1;i<=n;i++)
          scanf("%lld",&s[i]);
        sort(s+1,s+1+n);
        for(int i=1;i<=n;i++)
        {
            num+=s[i];
            if(num<1ll*i*(i-1)/2){
                vis=1;break;
            }
        }
        if(vis==1||num!=1ll*n*(n-1)/2) printf("The data have been tampered with!\n");
        else printf("It seems to have no problem.\n");
    }
}
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值