九野的博客,转载请注明出处:http://blog.csdn.net/acmmmm/article/details/11877509
修改后的题意是:
n个点,下面n行
i行表示与i点相连的单向边,为0表示该行输入结束
问: 把点分到2个图中,每个图都要保证是完全图能否做到
问题等价于 保证不认识的不在同一个图里
显然这个图的补图就是一个二分图,BFS交叉染色判断图是否为二分图
代码1:
#include <iostream>
#include <string>
#include <cstring>
#include <algorithm>
#include <cstdio>
#include <cctype>
#include <queue>
#include <stdlib.h>
#include <cstdlib>
#include <math.h>
#include <set>
#include <vector>
#define inf 107374182
#define N 200
#define M 20001
#define ll int
using namespace std;
inline ll Max(ll a,ll b){return a>b?a:b;}
inline ll Min(ll a,ll b){return a<b?a:b;}
struct Edge{
int f,t;
}edge[M];
int edgenum;
void addedge(int u,int v){
Edge E={u,v,};
edge[edgenum]=E;
edgenum++;
}
//不认识的人一定在不同集合
int map[N][N];
int in[N],n;
bool BFS(int x){
queue<int>q;
q.push(x);
in[x]=0;
while(!q.empty()){
x=q.front(); q.pop();
for(int i=1;i<=n;i++)
{
if(i==x || map[i][x]==1)continue;//x和i认识就不用考虑
if(in[i]==-1)
{
in[i]=in[x]^1;
q.push(i);
}
else if(in[i]==in[x])return 1;
}
}
return 0;
}
int main()
{
int i,j,m;
while(~scanf("%d",&n)){
edgenum=0;
memset(map,0,sizeof(map));
for(i=1;i<=n;i++){
scanf("%d",&m);
while(m!=0){
map[i][m]=true;
scanf("%d",&m);
}
}
for(i=1;i<=n;i++)
for(j=1;j<=n;j++)
if(map[i][j]==0)map[j][i]=0;
memset(in,-1,sizeof(in));
for(i=1;i<=n;i++)
if(in[i]==-1)
if(BFS(i))break;
if(i>n)printf("YES\n");
else printf("NO\n");
}
return 0;
}
贴个学长的代码
#include<stdio.h>
#include<iostream>
#include<algorithm>
#include<cstring>
using namespace std;
//const int inf = 1000000000;
const int N = 500;
const int M = N*N;
struct E{
int v,next;
}e[M];
int head[N],k;
int belong[N],bcnt,dfn[N],low[N],ind;
int stack[N],top;
bool vis[N];
int n;
void add(int u,int v){
e[k].v = v;
e[k].next = head[u];
head[u] = k++;
}
void tarjan(int u){
dfn[u] = low[u] = ++ind;
vis[u] = true;
stack[top++] = u;
for(int i=head[u] ; i!=-1 ; i=e[i].next){
int v = e[i].v;
if(!dfn[v]){
tarjan(v);
if(low[u] > low[v])
low[u] = low[v];
}else if(vis[v] && dfn[v] < low[u])
low[u] = dfn[v];
}
if(low[u] == dfn[u]){
bcnt++;
int temp;
do{
temp = stack[--top];
vis[temp] = false;
belong[temp] = bcnt;
}while(u != temp);
}
}
void init(){
memset(head,-1,sizeof(head));
memset(dfn,0,sizeof(dfn));
memset(low,0,sizeof(low));
memset(vis,0,sizeof(vis));
k = top = ind = bcnt = 0;
}
int mp[N][N];
bool ok()
{
bool flag=1;
int i;
init();
for(int i=1;i<=n;i++)
for(int j=i+1;j<=n;j++)
if(mp[i][j]==0||mp[j][i]==0)
{
add(i,j+n);
add(j,i+n);
add(i+n,j);
add(j+n,i);
}
for(i=1 ; i <= 2*n ; ++i)
if(!dfn[i]) tarjan(i);
for(i=1 ; i <=n ; ++i)
if( belong[i] == belong[i+n] )
flag=0;
return flag;
}
int main()
{
int x;
while(scanf("%d",&n)!=EOF)
{
memset(mp,0,sizeof(mp));
for(int i=1;i<=n;i++)
{
while(1){
scanf("%d",&x);
if(x==0)
break;
mp[i][x]=1;
}
}
if(ok())
printf("YES\n");
else
printf("NO\n");
}
return 0;
}