5 4 0 0
1 3
1 4
3 5
4 5
5 4 1 0
1 3
1 4
3 5
4 5
2
NO
YES
(引用)题意比较不明…看了很久才搞出来 个人理解 就是:
n个人 给定m对关系:a,b不在一个集合中
已知x个人是好球员的集合中的人
y个人是坏球员
判断是否能分成2个集合
如果1是好球员 2是坏球员
其余的球员与1,2无关系 能分成2个集合 也算YES
思路:判定二分图模板一上,先从确定阵营的人开始染色,如果矛盾,NO;
再把上次dfs还没确定的人染色,如果矛盾,NO;
最后检查有没有没确定阵营的,有的话,NO;
其余情况YES;
#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cmath>
#include <algorithm>
#include <cstring>
#include <stack>
#include <cctype>
#include <queue>
#include <string>
#include <vector>
#include <set>
#include <map>
#include <climits>
#define lson root<<1,l,mid
#define rson root<<1|1,mid+1,r
#define fi first
#define se second
#define ping(x,y) ((x-y)*(x-y))
#define mst(x,y) memset(x,y,sizeof(x))
#define mcp(x,y) memcpy(x,y,sizeof(y))
#define Min(x,y) (x<y?x:y)
#define Max(x,y) (x>y?x:y)
using namespace std;
#define gamma 0.5772156649015328606065120
#define MOD 1000000007
#define inf 0x3f3f3f3f
#define N 5005
#define maxn 10005
typedef long long LL;
typedef pair<int,int> PII;
int pic[1001][1001];
int vis[200005],n,m;
void init(){
for(int i=0;i<n;i++)
vis[i]=-2; //没有染色就是-2
mst(pic,0);
}
int dfs(int x,int c){
//if(vis[x]!=0&&vis[x]==c)return 0; //这模板有毒,这句让我WA吐血了
vis[x]=c;
for(int i=0;i<n;++i){
if(pic[x][i]){
if(vis[i]==0)
dfs(i,-c);
else if(vis[i]==c)return 0;
}
}
return 1;
}
int main(){
int i,j,group,Case=0,x,y,X,Y,a;
while(scanf("%d%d%d%d",&n,&m,&X,&Y)!=EOF){
init();
//if(n==0)break;
for(i=0;i<m;i++){
scanf("%d%d",&x,&y);
x--;y--;
vis[x]=vis[y]=0; //阵营不明确的
pic[x][y]=pic[y][x]=1;
}
while(X--){scanf("%d",&a);a--;vis[a]=1;}//确定阵营的
while(Y--){scanf("%d",&a);a--;vis[a]=-1;}//与上边对立
bool flag=false;
for(i=0;i<n;i++){
if(vis[i]==1){
if(!dfs(i,1)){flag=true;printf("NO\n");break;}
}
else if(vis[i]==-1){
if(!dfs(i,-1)){flag=true;printf("NO\n");break;}
}
}
if(flag)continue;
for(i=0;i<n;i++){
if(vis[i]==0){ //还剩的阵营不明确的再尝试分配,分给1和0都行
if(!dfs(i,1)){flag=true;printf("NO\n");break;}
}
}
if(flag)continue;
for(i=0;i<n;i++){
if(vis[i]==-2){
flag=true;printf("NO\n");break;
}
}
if(flag)continue;
printf("YES\n");
}
return 0;
}
别人的二分图判断:
- #include<bits/stdc++.h>
- #include <cstdio>
- #include <algorithm>
- using namespace std;
- typedef long long ll;
- typedef pair<int,int> pll;
- const int N=5*1e4+1000;
- #define eps 1e-4
- int co[10005];
- int vis[10005];
- vector<int>g[10005];
- int dfs(int u)
- {
- int sz=g[u].size();
- for(int i=0; i<sz; i++)
- {
- int v=g[u][i];
- if(!co[v])
- {
- co[v]=!co[u];
- if(!dfs(v))
- return 0;
- }
- else if(co[u]==co[v])
- {
- return 0;
- }
- }
- return 1;
- }
- int main()
- {
- int n,m,x,y;
- while(cin>>n>>m>>x>>y)
- {
- for(int i=0; i<10005; i++)
- g[i].clear();
- if(n==1)
- {
- puts("NO");
- continue;
- }
- for(int i=0; i<m; i++)
- {
- int xx,yy;
- scanf("%d%d",&xx,&yy);
- g[xx].push_back(yy);
- }
- memset(co,0,sizeof(co));
- for(int i=0; i<x; i++)
- {
- int xx;
- scanf("%d",&xx);
- co[xx]=1;
- }
- for(int i=0; i<y; i++)
- {
- int xx;
- scanf("%d",&xx);
- co[xx]=0;
- }
- if(x==0&&y==0)
- puts("NO");
- else
- {
- int flag=1;
- for(int i=1; i<=n; i++)
- if(!dfs(i))
- flag=0;
- if(flag)
- puts("YES");
- else
- puts("NO");
- }
- }
- return 0;
- }
别人的种类并查集:
#include<bits/stdc++.h>
using namespace std;
#define mod 1000000007
#define PI acos(-1.0)
#define INF 0x3f3f3f3f
typedef long long LL;
typedef unsigned long long ULL;
const int maxn=1005;
int N,M,X,Y;
int a,b;
int ok;
struct node{
int father,rel;
}F[maxn];
bool vis[maxn];
int kind[maxn];
void init(){
ok=1;
memset(kind,-1,sizeof(kind));
memset(vis,0,sizeof(vis));
for(int i=1;i<=N;i++){
F[i].father=i;
F[i].rel=0;
}
}
int Find(int x){
if(F[x].father==x)return x;
int temp=F[x].father;
F[x].father=Find(F[x].father);
F[x].rel=F[x].rel^F[temp].rel;
return F[x].father;
}
bool Uion(int x,int y){
int fa,fb;
fa=Find(x);
fb=Find(y);
F[fa].rel=F[x].rel^F[y].rel^1;
if(fa==fb&&F[fa].rel!=0)return 0;
if(fa!=fb)F[fa].father=fb;
return 1;
}
bool go(int x){
int fa=Find(x);
if(kind[fa]>=0){
return kind[fa]^kind[x]==F[x].rel;
}
else {
kind[fa]=kind[x]^F[x].rel;
}
}
int main()
{
while(~scanf("%d%d%d%d",&N,&M,&X,&Y)){
init();
while(M--){
scanf("%d%d",&a,&b);
ok=(ok&&Uion(a,b));
vis[a]=vis[b]=1;
}
while(X--){
scanf("%d",&a);
vis[a]=1;
if(kind[a]==1)ok=0;
else {
kind[a]=0;
ok=(ok&&go(a));
}
}
while(Y--){
scanf("%d",&a);
vis[a]=1;
if(kind[a]==0)ok=0;
else {
kind[a]=1;
ok=ok&&go(a);
}
}
for(int i=1;i<=N;i++){
ok=(ok&&vis[i]);
}
if(ok){
printf("YES\n");
}
else {
printf("NO\n");
}
}
return 0;
}
别人的并查集+dfs
并查集
x的球员设置在集合1 y的在集合0
先以x和y的球员作为起点 dfs确定球员关系
如果dfs中发现关系矛盾 ->NO
dfs完了 如果还有球员没确定集合 随便给一个没集合的球员设个集合
以该球员作为起点dfs
如果dfs完了 还有球员不能确定集合 ->NO
否则YES
坑爹的是!!!!!居然爆栈………
于是dfs改成队列…..就过了