hdu4324-Triangle LOVE-2012 Multi-University Training Contest题解

Brief Description:

给定一个n*n的矩阵A,A[i][j]=1表示i喜欢j,A[i][j]=0表示i不喜欢j。规定A[i][i]=0且对任意i,j(i!=j)有A[i][j]=1或A[j][i]=1,且A[i][j]!=A[j][i],表示任意2个人一定存在喜欢关系,但是不能互相喜欢,即在有向图,保证任意两点间仅有一条有向边。现在若发现有i喜欢j,j喜欢k,k喜欢i(三角恋关系)则输出"Yes",否则输出"No"。


Analysis:
比赛时这题队友暴力过的,但是对于n=2000,O(n^2)的算法比较妥当。
下面介绍O(n^2)的解法:
首先从i从0到n-1依次枚举,当前枚举到i时,可以将之前的0到i-1划分为2个部分left和right,i喜欢left中的每一个人,right中的每一个人喜欢i,现在的关键是能否找到left中的k喜欢right中的某一个人p,这样就找到了i->k->p->i,满足条件。
我们可以统计left中点的入度和lin(把left中每个点的入度加起来),出度和lout,left中节点个数l,right中节点个数r,
若lin-lout=r*l,则此时不存在三角恋,否则存在三角恋。
具体看以下代码:

#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cmath>

using namespace std;
const int maxn = 2005;
char a[maxn][maxn];
bool vis[maxn];
int n;
int main()
{
    int cas,ta=1;
    scanf("%d",&cas);
    while(cas--){
        int i,j,lin,lout,l,r;
        scanf("%d",&n);
        for(i=0; i<n; i++) scanf(" %s",a[i]);

        int in[maxn]={0},out[maxn]={0};
        for(i=0; i<n; i++){
           if(i < 2){
              if(i == 1){
                if(a[0][1] == '1') in[1]=1,out[0]=1;
                else in[0]=1,out[1]=1;
              }
              continue;
           }

           l = lin = lout = 0;
           for(j=0; j<i; j++) // 2012_9_13评注:i是三角恋中序号最大的
              if(a[i][j] == '1'){
                 l++; // left多1
                 lin += in[j];  lout += out[j];  out[i]++;   in[j]++;
              }else{
                 out[j]++;   in[i]++;
              }
           r = i - l;
           if(lin-lout != r*l) break;
        }
        printf("Case #%d: ",ta++);
        if(i < n) puts("Yes");
        else puts("No");
    }
    return 0;
}



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值