当前位置:   article > 正文

【算法笔记】竞赛图(有向完全图)(相关题型总结)

竞赛图

整理的算法模板合集: ACM模板


竞赛图(有向完全图)

竞赛图也叫有向完全图。每对顶点之间都有一条边相连的有向图称为竞赛图

竞赛图的一些简单的性质:

  • 竞赛图没有自环,没有二元环;若竞赛图存在环,则一定存在三元环。(如果存在一个环大于三元,那么一定存在另一个三元的小环。)
  • 任意竞赛图都有哈密顿路径(经过每个点一次的路径,不要求回到出发点)。
  • 图存在哈密顿回路的充要条件是强联通。
  • 哈密顿问题中,对于 n 阶竞赛图,当 n 大于等于 2 时一定存在哈密顿通路

设 D 为 n 阶有向简单图,若 D 的基图为 n 阶无向完全图,则 D 为 n 阶竞赛图。

简单来说,竞赛图就是将完全无向图的无向边给定了方向。

一、兰道定理

兰道定理(Landau’s Theorem)是用来判定竞赛图的定理。
将一个竞赛图的每一个点的出度从小到大排序后得到的序列称为竞赛图的比分序列

在这里插入图片描述

例题HDU 5873 Football Games

题目大意:
现在有比赛,所有队伍两两进行比赛,赢的积2分,输的积0分,如果平局的话就各自都积1分,现在给出每只队伍的得分情况,判断是否合法。

思路:
给出的 m 个队伍可以构成一个竞赛图,问得分情况是否合法实质是在问竞赛图是否合法
根据竞赛图的兰道定理,将得分视为比分序列,将所有得分进行排序,然后依次处理:由于每次比赛胜利都会使得总分 +2,那么前 i 只队伍的得分情况必须大于等于 i*(i-1),当判断到最后一只队伍时,有前 n-1 只队伍的得分必须大于 n*(n-1)

int a[N];
int main(){
   
    int t;
    while(scanf("%d",&t)!=EOF){
   
        while(t--){
   
            int n;
            scanf("%d",&n);
            for(int i=1;i<=n;i++)
                scanf("%d",&a[i]);
            sort(a+1,a+1+n);
 
            int sum=0;
            bool flag=true;
            for(int i=1;i<=n;i++){
   
                sum+=a[i];
                if(i<=n-1){
   
                    if(sum<i*(i-1)){
   
                        flag=false;
                        break;
                    }
                }
                else{
   
                    if(sum!=i*(i-1)){
   
                        flag=false;
                        break;
                    }
                }
            }
 
            if(flag)
                printf("T\n");
            else
                printf("F\n");
        }
    }
    return 0;
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45

来源

二、求竞赛图的任意三元环

CF117C Cycle(dfs爆搜)
题目传送门

在这里插入图片描述

因为竞赛图(有向完全图)如果存在环的话就一定存在三元环
我们直接暴力dfs即可,如果x到y,y能到x的fa,那么fa,x,y三个点就形成了一个三元环。如果找到三元环就直接退出。

const int N = 5007, M = 5000007, INF = 0x3f3f3f3f;
int n, m;
char s[N][N];

bool vis[N];

bool dfs(int x , int fa)
{
   
    vis[x] = 1;
    for(int i = 1; i <= n; ++ i){
   
        if(s[x][i] - '0'){
   
            if(s[i][fa] - '0'){
   
                printf
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/小蓝xlanll/article/detail/64631
推荐阅读
相关标签
  

闽ICP备14008679号