hdu 4751

12 篇文章 0 订阅
8 篇文章 0 订阅

一个人就是弱···做这个题做了四个小时···一直WA开始以为两个动态数组当作两个组,依次把每个人加入就好,还真觉得没什么问题。。。思维好搓啊,哪里可以这么简单。后面下来才知道这是一个tow_sat问题,第一次听说这个名词···,大概和二分图差不多,既然要分组,那么不认识的肯定不能在同一组,用两个标记进行排斥分组就好,但得注意此处的单方认识也要当作不认识,后面枚举每个点进行一遍dfs()查找是否有矛盾就好,这是很基础的一个模型,要好好体会这种思想。

#include<cstdio>
#include<cstring>


int G[105][105];
int color[105];
int n;


int dfs(int x){
     for(int i=1;i<=n;i++){
          if(G[x][i]||x==i)continue;
          if(color[i]!=0&&color[i]==color[x])return 0;//如果出现矛盾就返回0代表不可能 
          else{
               color[i]=0-color[x];//由于不认识就得染上不同颜色 
               if(!dfs(i))return 0;//继续dfs 
          }
     }
     return 1;
}


int main(){
     while(scanf("%d",&n)!=EOF){
         int u;
         memset(G,0,sizeof(G));
         memset(color,0,sizeof(color));
         for(int i=1;i<=n;i++)
             while(scanf("%d",&u)&&u)G[i][u]=1;
         //单方认识在这里也算互不认识
         for(int i=1;i<=n;i++)
            for(int j=1;j<=n;j++)if(G[i][j]&&!G[j][i])
            {    G[i][j]=G[j][i]=0;        } 
         
         int i;
         for(i=1;i<=n;i++){
             if(color[i]!=0)continue;
             color[i]=1;//既然是最初的分组或者是朋友就可以分在这个组里面 
             if(!dfs(i))break; 
         }
         if(i>n)printf("YES\n");
         else printf("NO\n"); 
     }
     return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值