题意: 一群马,分成两组。每组中任意一头马不能有超过1只以上的敌对马和他在同一组。求合法分组。
思路: 一开始想不通怎么判断无解,2-sat貌似也不能判断这种无解情况。后来仔细分析发现,对于任一马的摆放分三种情况:
1.他有一只敌对马。那么他放哪组都行。
2.他有两只敌对马。那么这两只敌对马的摆放有2种可能,(1,1)和(2,0)((0,2)和(2,0)同属一种情况)。对于前一种他放哪组都行,后一种只能放在没冲突那组。
3.他有三只敌对马。那么三只的摆放有3种,(1,2),(2,1),(3,0)。这三种情况都存在能放他的组。
综上分析,对任一马,不论什么情况,都能找到可放置的组,所以不存在无解的情况。既然没有无解,就大胆的搜好了。。。
代码:
#include<stdio.h>
#include<vector>
using namespace std;
#define N 100010
vector<int> v[3*N];
int ans[3*N];
void dfs(int x)
{
int i,cnt=0;
for(i=0;i<v[x].size();i++)
if(ans[x]==ans[v[x][i]])
cnt++;
if(cnt>1){
ans[x]^=1;
for(i=0;i<v[x].size();i++)
if(ans[x]==ans[v[x][i]])
dfs(v[x][i]);
}
}
int main()
{
int i,n,m,x,y;
scanf("%d%d",&n,&m);
while(m--){
scanf("%d%d",&x,&y);
v[x].push_back(y);
v[y].push_back(x);
}
for(i=1;i<=n;i++)
dfs(i);
for(i=1;i<=n;i++)
printf("%d",ans[i]);
}