zoukankan      html  css  js  c++  java
  • 2sat

    之前做的两发

    https://vjudge.net/problem/UVALive-3211

    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    #include<cmath>
    using namespace std;
    const int maxn = 2007;
    int t[maxn][2], n, tot, S[maxn*2], scnt;
    bool mark[maxn*2];
    struct Edge{
        int v, nxt;
        Edge(){}
        Edge(int v, int nxt):v(v), nxt(nxt){}
    }edge[maxn*maxn*4];
    int head[maxn*2];
    void addedge(int u, int v){
        edge[tot] = Edge(v, head[u]);
        head[u] = tot++;
    }
    void conj(int x, int detx, int y, int dety){
        x = 2*x+detx;
        y = 2*y+dety;
        addedge(x^1, y);
        addedge(y^1, x);
    }
    void build(int mid){
        tot = 0;
        memset(head, -1, sizeof head);
        for(int i = 0; i < n; i++)
            for(int a = 0; a < 2; a++)
                for(int j = i+1; j < n; j++)
                    for(int b = 0; b < 2; b++)
                        if(fabs(t[i][a]-t[j][b]) < mid)
                            conj(i, a^1, j, b^1);
        
    }
    bool dfs(int x){
        if(mark[x])
            return true;
        if(mark[x^1])
            return false;
        mark[x] = true;
        S[scnt++] = x;
        for(int i = head[x]; ~i; i = edge[i].nxt){
            int v = edge[i].v;
            if(!dfs(v))
                return false;
        }
        return true;
    }
    bool solve(){
        memset(mark, false, sizeof mark);
        for(int i = 0; i < 2*n; i+=2){
            if(!mark[i]&&!mark[i+1]){
                scnt = 0;
                if(!dfs(i)){
                    for(int j = 0; j < scnt; j++){
                        mark[S[j]] = false;
                    }
                    scnt = 0;
                    if(!dfs(i+1))
                        return false;
                }
            }
        }
        return true;
    }
    int main(){
        while(scanf("%d", &n)==1 && n){
            for(int i = 0; i < n; i++)
                for(int j = 0; j < 2; j++){
                    scanf("%d", &t[i][j]);
                }
            int l = 0, r = 1e7;
            while(l < r){
                int mid = (r-l+1)/2+l;
                build(mid);
                if(solve())
                    l = mid;
                else
                    r = mid-1;
            }
            printf("%d
    ", l);
        }
        return 0;
    }
    /*
     10
     44 156
     153 182
     48 109
     160 201
     55 186
     54 207
     55 165
     17 58
     132 160
     87 197
    */
    View Code

    https://vjudge.net/problem/UVALive-3713

    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    #include<cmath>
    using namespace std;
    const int maxn = 100007;
    int age[maxn], n, m, tot, S[maxn*2], scnt;
    double ave;
    bool mark[maxn*2];
    struct Edge{
        int v, nxt;
        Edge(){}
        Edge(int v, int nxt):v(v), nxt(nxt){}
    }edge[100007*4];
    int head[maxn*2];
    void addedge(int u, int v){
        edge[tot] = Edge(v, head[u]);
        head[u] = tot++;
    }
    void conj(int x, int detx, int y, int dety){
        x = 2*x+detx;
        y = 2*y+dety;
        addedge(x^1, y);
        addedge(y^1, x);
    }
    bool dfs(int x){
        if(mark[x])
            return true;
        if(mark[x^1])
            return false;
        mark[x] = true;
        S[scnt++] = x;
        for(int i = head[x]; ~i; i = edge[i].nxt){
            int v = edge[i].v;
            if(!dfs(v))
                return false;
        }
        return true;
    }
    bool solve(){
        memset(mark, false, sizeof mark);
        for(int i = 0; i < 2*n; i+=2){
            if(!mark[i]&&!mark[i+1]){
                scnt = 0;
                if(!dfs(i)){
                    for(int j = 0; j < scnt; j++){
                        mark[S[j]] = false;
                    }
                    scnt = 0;
                    if(!dfs(i+1))
                        return false;
                }
            }
        }
        return true;
    }
    int main(){
        while(scanf("%d%d", &n, &m)){
            tot = 0;
            memset(head, -1, sizeof head);
            if(!n&&!m)
                break;
            double sum = 0;
            for(int i = 0; i < n; i++){
                scanf("%d", &age[i]);
                sum += age[i];
            }
            ave = sum/n;
            while(m--){
                int u, v;
                scanf("%d%d", &u, &v);
                u--;
                v--;
                if((age[u]<ave&&age[v]<ave) || (age[u]>=ave&&age[v]>=ave)){
                    conj(u, 0, v, 0);
                    conj(u, 1, v, 1);
                }
                else{
                    conj(u, 1, v, 1);
                }
            }
            if(!solve()){
                puts("No solution.");
            }
            else{
                for(int i = 0; i < 2*n; i+=2){
                    if(mark[i]){
                        printf("C
    ");
                    }
                    else{
                        if(age[i/2]>=ave)
                            printf("A
    ");
                        else
                            printf("B
    ");
                    }
                }
            }
        }
        return 0;
    }
    /*
     16 20 21
     22
     23
     24
     25
     26
     27
     28 101 102 103 104 105 106 107 108
     1 2 3 4 5 6 7 8
     9 10 11 12 13 14 15 16 1 10 2 9
     3 12 4 11 5 14 6 13 7 16 8 15 1 12 1 13 3 16 6 15 0 0*/
    View Code

    由于拆点,点数应该是2n...

    每个字句a|b 加边!a -> b, !b -> a, 两条边呢...

    点和边开的不够大,一言不合就爆掉了...

    搞图论是没有用的,转行做数学题了hh
  • 相关阅读:
    phpstorm 使用 Xdebug 调试代码
    frp 实现内网穿透(Windows 版)
    update-alternatives 使用详解
    Linux 虚拟机使用 xshell 连接 (debian、kali、CentOS)
    PHP xml 转数组 数组转 xml 操作
    Mac上查看当前安卓手机上打开的app的包名和主程序入口
    启动appium server时打印日志时间
    App自动化测试框架学习探索--从零开始设计
    System.getProperty("user.dir")获取的到底是什么路径?
    读取Excel文件,抛出类似Cleaning up unclosed ZipFile for archive D:projectmyTestautoAppUIexcelMode用例模板2.xlsx 错误解决
  • 原文地址:https://www.cnblogs.com/DearDongchen/p/7868515.html
Copyright © 2011-2022 走看看