这是个无比暴力的模板
但是
从来没有没卡过!!!
判是否存在解
流程:标记i并传递标记,直到结束或出现矛盾。
bool mark[M];
int stk[M],top;
bool dfs(int x){
if(mark[x^1])return 0;
if(mark[x])return 1;
mark[x]=1;
stk[++top]=x;
for(int i=head[x];i;i=G[i].nxt){
if(!dfs(G[i].to))return 0;
}
return 1;
}
bool check() {
for(int i=0;i<n*2;i+=2){
if(!mark[i]&&!mark[i+1]){
top=0;
if(!dfs(i)){
while(top)mark[stk[top--]]=0;
if(!dfs(i+1))return 0;
}
}
}
return 1;
}
输出方案
根据mark的定义输出即可
for(int i=0; i<2*n; i+=2) {
if(mark[i]) {
printf("%d",??);
} else {
printf("%d",??);
}
}
还有一种方法 tarjan
流程:求出强连通分量,如果i*2和i*2+1在一个强连通分量里,则无解
void tarjan(int x){
dfn[x]=low[x]=++tot;
stk[++top]=x;
vis[x]=1;
for(int i=head[x]; i; i=G[i].nxt) {
int y=G[i].to;
if(!dfn[y]) {
tarjan(y);
low[x]=min(low[x],low[y]);
} else if(vis[y]) {
low[x]=min(low[x],dfn[y]);
}
}
if(low[x]==dfn[x]) {
int y;
cnt++;
do {
y=stk[top--];
vis[y]=0;
col[y]=cnt;
} while(y!=x);
}
}
输出方案:
把强连通分量用反边连接,构成新图
按拓扑序标记选和不选,传递不选标记