hdu4751Divide Groups(dfs枚举完全图集合或者bfs染色)

/*************************************************************************
    > File Name: j.cpp
    > Author: HJZ
    > Mail: 2570230521@qq.com
    > Created Time: 2014年08月28日 星期四 12时26分13秒
 ************************************************************************/

//提議:能否將一個給定的有向圖,變成兩個完全圖(任意兩點都直接相連,雙向邊)

#include <queue>
#include <string>
#include <cstdio>
#include <stack>
#include <cstring>
#include <iostream>
#include <algorithm>
#define N 105
using namespace std;

int a[N], b[N];
//a, b集合初始化爲空!
int g[N][N];
int n;

bool flag;

bool dfs(int u, int la, int lb){
   if(u>n && la+lb==n) return true;//如果a ,b集合中的元素數目恰好是n,則說明可以形成兩個完全圖!
   bool flagx=true;
   for(int i=0; i<la && flagx; ++i)
       if(!(g[a[i]][u] && g[u][a[i]]))
           flagx=false;
   if(flagx) a[la]=u;//如果u節點可以放入a集合中
   if(flagx && dfs(u+1, la+1, lb)) return true;
   bool flagy=true;
   for(int i=0; i<lb && flagy; ++i)
       if(!(g[b[i]][u] && g[u][b[i]]))
            flagy=false;
   if(flagy) b[lb]=u;//如果u節點可以放入b集合中
   if(flagy && dfs(u+1, la, lb+1)) return true;
   return false;
}

int main(){
   while(scanf("%d", &n)!=EOF){
      memset(g, 0, sizeof(g));
      for(int i=1; i<=n; ++i){
         int v;
         vis[i]=0;
         while(scanf("%d", &v) && v)
           g[i][v]=1;
      }
     flag=dfs(1, 0, 0);
     if(flag)
         printf("YES\n");
     else printf("NO\n");
   }
   return 0;
}
/*************************************************************************
    > File Name: j.cpp
    > Author: HJZ
    > Mail: 2570230521@qq.com
    > Created Time: 2014年08月28日 星期四 12时26分13秒
 ************************************************************************/
//思路:bfs,和判断二分图差不多,将图分成两个集合,如果a和b都有g[a][b]&&g[b][a]说明
//a和b一定在同一个集合中,如果有a,b不在一个集合中,a,c不在同一个集合中,b,c也不在同一个
//集合中,出现矛盾!也就是这个图不能分成两个完全图!
#include <queue>
#include <string>
#include <cstdio>
#include <stack>
#include <cstring>
#include <iostream>
#include <algorithm>
#define N 105
using namespace std;
queue<int>q;
int g[N][N];
int coll[N];
int n;

bool bfs(int u){
    while(!q.empty())  q.pop();
    q.push(u);
    while(!q.empty()){
        int x=q.front();
        q.pop();
        for(int y=1; y<=n; ++y){
           if(x==y || g[x][y]&&g[y][x]) continue;
           if(coll[y]==-1){
                coll[y]=coll[x]^1;
                q.push(y);
           }
           else if(coll[y]==coll[x])
                return true;
        }
    }
    return false;
}

int main(){
   while(scanf("%d", &n)!=EOF){
       memset(g, 0, sizeof(g));
       for(int i=1; i<=n; ++i){
            int v;
            while(scanf("%d", &v) && v)
                g[i][v]=1;
            coll[i]=-1;
       }
       int i;
       for(i=1; i<=n; ++i){
           if(coll[i]==-1){
               coll[i]=0;//默认是在集合0中
               if(bfs(i)) break;
           }
       }
       if(i<=n) printf("NO\n");
       else printf("YES\n");
   }
   return 0;
}
时间: 2024-12-25 09:32:54

hdu4751Divide Groups(dfs枚举完全图集合或者bfs染色)的相关文章

【转载】OpenEJB 3.0支持对枚举和集合的依赖注入及OSGi和EJB 3.0特性

    开源轻量级EJB实现框架OpenEJB的最新版支持对枚举.集合和Maps的依赖注入(Dependency Injection,即DI),并且支持OSGi和EJB 3.0规范.在经历了一年半的开发后,OpenEJB 3.0最终版近期发布了.该版本还支持@EJB引用其他EAR文件中的本地接口.事务日志及基于HTTP协议的EJBd,同时它还支持EJB 3.0的新特性如Business Interfaces.Java Persistence API (JPA)及JAX-WS Web Servic

UVa 10717 Mint:DFS枚举4个数的lcm

10717 - Mint Time limit: 3.000 seconds http://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&category=115&page=show_problem&problem=1658 The Royal Canadian Mint has commissioned a new series of designer coffee tables, with l

Java实现高效的枚举元素集合

Set是Java集合类的重要组成部分,它用来存储不能重复的对象.枚举类型也要求其枚举元素各不相同.看起来枚举类型和集合是很相似的.然而枚举类型中的元素不能随意的增加.删除,作为集合而言,枚举类型非常不实用.EnumSet是专门为enum实现的集合类,本实例将演示其用法. 思路分析:可以通过为EnumSet指定类型,该类型即为在同一包中定义的枚举类.使用EnumSet类的add()方法添加元素,使用EnumSet类的remove()方法删除元素,使用EnumSet类的complementOf()方

《Head First C#》 枚举与集合中学习问题

问题描述 关于C#中枚举集合里列表排序的问题,敲完代码后一堆的问题,求大神指点.一个建立鸭子列表并排序的程序Duck类{classDuck:IComparable<Duck>{publicintSize;publicKindOfDuckKind;publicintCompareTo(DuckduckToCompare){if(this.Size>duckToCompare.Size)return1;elseif(this.Size<duckToCompare.Size)return

poj 1950 Dessert(dfs枚举,模拟运算过程)

/* 这个代码运行的时间长主要是因为每次枚举之后都要重新计算一下和的值! 如果要快的话,应该在dfs,也就是枚举的过程中计算出前边的数值(这种方法见第二个代码),直到最后,这样不必每一次枚举都要从头再算一遍值! */ #include<iostream> #include<cstring> #include<cstdio> #include<algorithm> using namespace std; char ch[20]; char sign[3]={

topcoder 2C 1000 WellTimedSearch dfs+枚举

          首先上题解的传送门.        这个关键就是求出个f(x,A)也就是x结点在A层所需要的额外点数.我们所要求的就是枚举x,然后判断A-B层中的节点数,取最大值除以N即是我们要求的最大概率        求解f(x,A)时直接dfs,因为f(1,1)=1 ,f(x,A)=ceil(x/2) + f(ceil(x/2), A-1)  题解: int getLesser(int A, int x) { if (x == 1) { // cut execution time, i

codeforce Pashmak and Buses(dfs枚举)

/* 题意:n个同学,k个车, 取旅游d天! 要求所有的学生没有两个或者两个以上的在同一辆车上共同带d天! 输出可行的方案! 对于d行n列的矩阵,第i行第j列表示的是第i天第j个同学所在的车号! 也就是保证所有行不全相同,即每一列都是不相同的! 如果每一列都不相同就是表示第j个同学(第j列)在这d天中不会和其他同学(列)在这d天中 都在同一辆车中! 思路:对于每一列我们枚举d天该学生所在的车号!它的下一列只保证有一个元素和它不同就行了!依次下去! 还有一共有 d 个位置来填充车号(1....k)

HDU 2489 Minimal Ratio Tree (DFS枚举+最小生成树Prim)

链接: HDU : http://acm.hdu.edu.cn/showproblem.php?pid=2489 POJ  : http://poj.org/problem?id=3925 题目: Problem Description For a tree, which nodes and edges are all weighted, the ratio of it is calculated according to the following equation. Given a comp

java实现高效的枚举元素集合示例_java

思路分析:可以通过为EnumSet指定类型,该类型即为在同一包中定义的枚举类.使用EnumSet类的add()方法添加元素,使用EnumSet类的remove()方法删除元素,使用EnumSet类的complementOf()方法获取对象的全部,使用EnumSet类的range()方法获取指定范围的元素. 代码如下: 复制代码 代码如下: package cn.edu.xidian.crytoll;public enum Weeks {    MONDAY, TUESDAY, WEDNESDAY