• HDU4421 Bit Magic 【2-sat】


    叙述性说明:


    这给出了一个矩阵,原来的请求a排列


    2-sat称号。对于每一位跑步边,跑31位可

    详细的施工方


    注意N=1的情况特判,还有检查对称元素是否同样


    #include <stdio.h>
    #include <string.h>
    #include <stdlib.h>
    #include <iostream>
    #include <vector>
    #include <math.h>
    #define pb push_back
    #include <algorithm>
    using namespace std;
    int V;
    const int MAX_V=1111;
    vector<int> G[MAX_V];
    vector<int> rG[MAX_V];
    vector<int> vs;
    bool used[MAX_V];
    int cmp[MAX_V];
    void add_edge(int from ,int to){
            //cout<<from<<"->"<<to<<endl;
            G[from].pb(to);
            rG[to].pb(from);
    }
    void dfs(int v){
            used[v]=true;
            //cout<<G[v].size()<<"---"<<endl;
            for(int i=0;i<G[v].size();i++)
                    if(!used[G[v][i]])
                            dfs(G[v][i]);
            vs.pb(v);
    }
    void rdfs(int v,int k){
            used[v]=true;
            cmp[v]=k;
            for(int i=0;i<rG[v].size();i++) if(!used[rG[v][i]]) rdfs(rG[v][i],k);
    }
    int scc(){
            memset(used,0,sizeof(used));
            memset(cmp,0,sizeof(cmp));
            vs.clear();
            for(int v=0;v<V;v++)
                    if(!used[v])
                            dfs(v);
            memset(used,0,sizeof(used));
            int k=0;
            for(int i=vs.size()-1;i>=0;i--)
                    if(!used[vs[i]])
                            rdfs(vs[i],k++);
            for(int i=0;i<MAX_V;i++){G[i].clear();rG[i].clear();}
            return k;
    }
    int g[555][555];
    int main(){
        #ifndef ONLINE_JUDGE
            freopen("G:/in.txt","r",stdin);
            //freopen("G:/out.txt","w",stdout);
        #endif
        int N;
        while(scanf("%d",&N)!=EOF){
            V=2*N;
            bool con=false;
            for(int i=0;i<N;i++)
                    for(int j=0;j<N;j++)
                            scanf("%d",&g[i][j]);
            if(N==1){//N=1特判
                    puts("YES");
                    continue;
            }
            for(int i=0;i<N && !con;i++)
                    for(int j=0;j<N && !con;j++){
                            if(g[i][j]!=g[j][i]){//对角线对称
                                    puts("NO");
                                    con=true;
                            }
                    }
            if(con)
                    continue;
            for(int now=0;now<=30;now++){
                    for(int i=0;i<N;i++)
                            for(int j=i+1;j<N;j++){
                                    int num=(g[i][j]>>now)&1;
                                    if((i&1)&&(j&1)){
                                            if(num){
                                                    add_edge(i+N,j);
                                                    add_edge(j+N,i);
                                            }else{
                                                    add_edge(i,i+N);
                                                    add_edge(j,j+N);
                                            }
                                    }else if(!(i&1)&&!(j&1)){
                                            if(num){
                                                    add_edge(i+N,i);
                                                    add_edge(j+N,j);
                                            }else{
                                                    add_edge(i,j+N);
                                                    add_edge(j,i+N);
                                            }
                                    }else{
                                            if(num){
                                                    add_edge(i,j+N);
                                                    add_edge(j+N,i);
                                                    add_edge(i+N,j);
                                                    add_edge(j,i+N);
                                            }else{
                                                    add_edge(i,j);
                                                    add_edge(j,i);
                                                    add_edge(i+N,j+N);
                                                    add_edge(j+N,i+N);
                                            }
                                    }
                            }
                    for(int i=0;i<2*N;i++)
                            for(int j=0;j<G[i].size();j++)
                                    //printf("%d->%d
    ",i,G[i][j]);
                    scc();
                    for(int i=0;i<N;i++)//2-sat无解条件
                            if(cmp[i]==cmp[N+i]){
                                    puts("NO");
                                    con=true;
                                    break;
                            }
                    if(con) break;
            }
            if(con) continue;
            puts("YES");
        }
    }
    


    版权声明:本文博客原创文章。博客,未经同意,不得转载。

  • 相关阅读:
    基于vuedraggable的表单生成组件和基于paperjs的流程图组件
    笔记
    flex布局总结回顾
    layui表单验证
    vue打包后element-ui部分样式(图标)异常问题
    element-ui升级笔记;echarts图表100px问题
    a标签前端下载火狐兼容和笔记
    vue修改富文本中的元素样式
    ul列表li元素横排显示的IE兼容性问题
    iptables
  • 原文地址:https://www.cnblogs.com/gcczhongduan/p/4676513.html
Copyright © 2020-2023  润新知