hdu1814 Peaceful Commission 2-sat

hdu1814 Peaceful Commission

链接

emm,三个链接,三个都不同
loj随便做
hdu字典序最小
bzoj求合法方案数

思路

loj是任意一组解,直接跑tarjan然后判。
hdu是求最小字典序的2-sat解,真的是码力弱的要死呀。
只有O(N*M)的dfs复杂度能做。
如果不会2-sat的看这里

代码

#include <bits/stdc++.h>
using namespace std;
const int N=1e5+7;
int read() {
    int x=0,f=1;char s=getchar();
    for(;s>'9'||s<'0';s=getchar()) if(s=='-') f=-1;
    for(;s<='9'&&s>='0';s=getchar()) x=x*10+s-'0';
    return x*f;
}
int n,m;
struct node {
    int v,nxt;
}e[N];
int head[N],tot;
void add(int u,int v) {
//  cout<<u<<" "<<v<<"\n";
    e[++tot].v=v;
    e[tot].nxt=head[u];
    head[u]=tot;
}
int stak[N],top,vis[N];
bool dfs(int u) {
    if(vis[u]) return 1;
    if(vis[u^1]) return 0;
    vis[u]=1;
    stak[++top]=u;
    for(int i=head[u];i;i=e[i].nxt) {
        int v=e[i].v;
        if(!dfs(v)) return 0;
    }
    return 1;
}
void clear() {
    memset(head,0,sizeof(head));
    memset(vis,0,sizeof(vis));
    tot=0;
}
int main() {
//  freopen("a.in","r",stdin);
    while(scanf("%d%d",&n,&m)!=EOF) {
        clear();
        for(int i=1;i<=m;++i) {
            int x=read()-1,y=read()-1;
            add(x,y^1);
            add(y,x^1);
        }
        int flag=0;
        for(int i=0;i<n+n;i+=2) {
            if(!vis[i]&&!vis[i+1]) {
                top=0;
                if(!dfs(i)) {
                    while(top) vis[stak[top--]]=0;
                    if(!dfs(i+1)) {flag=1;break;}
                }
            }
        }
        if(flag) puts("NIE");
        else {
            for(int i=0;i<n+n;++i)
                if(vis[i]) printf("%d\n",i+1);
        }
    }   
    return 0;
}
 
全部评论

相关推荐

10-06 12:46
门头沟学院 Java
跨考小白:定时任务启动
点赞 评论 收藏
分享
点赞 收藏 评论
分享
牛客网
牛客企业服务