fzu2233 2-sat

#include <iostream>
#include <stdio.h>
#include <math.h>
#include <stdlib.h>
#include <string>
#include <string.h>
#include <algorithm>
#include <vector>
#include <queue>
#include <iomanip>
#include <time.h>
#include <set>
#include <map>
#include <stack>

using namespace std ;
const int maxn = 808 ;
int n ;
int val[maxn][maxn] ;
int c[maxn*maxn] ;

const   int N = maxn * 2  ;
const   int M = maxn * maxn  ;
struct  Edge{
        int u , v , next ;
        bool  sign  ; //是否为桥
}e[M];
int   lis[N] , id ;
void  add(int u , int v){
      e[id].sign = 0 ;
      e[id].u = u ;
      e[id].v = v ;
      e[id].next = lis[u] ;
      lis[u] = id++ ;
}

int  dfn[N] , low[N] ,stak[N] , top , Time ;
int  taj ; //分量标号
int  belong[N] ; //所属分量
bool instack[N] ;
vector<int> bcc[N] ; //分量所包含点

void tarjan(int u , int father){
     dfn[u] = low[u] = ++Time ;
     stak[top++] = u ;
     instack[u] = 1 ;
     for(int i = lis[u] ; i != -1 ; i = e[i].next){
         int v = e[i].v ;
         if(dfn[v] == -1){
              tarjan(v , u) ;
              low[u] = min(low[u] , low[v]) ;
              if(dfn[u] < low[v])
                 e[i].sign = 1 ;  //桥
         }
         else if(instack[v])
              low[u] = min(low[u] , dfn[v]) ;
     }
     if(low[u] == dfn[u]){
         int now ;
         taj++ ;
         bcc[taj].clear() ;
         do{
            now = stak[--top] ;
            instack[now] = 0 ;
            belong[now] = taj ;
            bcc[taj].push_back(now)  ;
         }while(now != u) ;
     }
}

void init(){
     memset(dfn , -1 , sizeof(dfn)) ;
     memset(instack , 0 , sizeof(instack)) ;
     memset(lis , -1 , sizeof(lis)) ;
     id = 0 ;
     top = Time = taj = 0 ;
}

bool judge(int limit){
    init() ;

    for(int u = 1 ; u <= n ; u++){
        for(int v = 1 ; v < u ; v++){
            if(val[u][v] < limit){
                add(u , v) ;
                add(v , u) ;
                add(u+n , v+n) ;
                add(v+n , u+n) ;
            }
        }
    }

    for(int i = 1 ; i <= n+n ; i++){
        if(dfn[i] == -1) tarjan(i , i) ;
    }

    for(int i = 1 ; i <= n ; i++){
         if(belong[i] == belong[i+n]) return false ;
    }
    int g = belong[1] , s1 = 0 , s2 = 0;
    for(int i = 1 ; i <= n ; i++){
        if(g == belong[i]) s1++ ;
    }

    g = belong[1+n] ;
    for(int i = 1 ; i <= n ; i++){
        if(g == belong[n+i]) s2++ ;
    }
    if(s1 == n && s2 == n) return false ;


    return true ;
}

int main(){
    int cnt ;
    while(scanf("%d" , &n) != EOF){
        cnt = 0 ;
        for(int i = 1 ; i <= n ; i++){
            for(int j = 1 ; j <= n ; j++){
                scanf("%d" , &val[i][j]) ;
                if(val[i][j] == -1) continue ;
                c[cnt++] = val[i][j] ;
            }
        }

        std::sort(c , c+cnt) ;
        int m = std::unique(c  ,c+cnt) - c ;

        int l = 0 , r = m-1 , mid  , s = 0  ;
        while(l <= r){
            mid = (l + r) >> 1 ;
            if(judge(c[mid])){
                s = c[mid] ;
                l = mid + 1 ;
            }
            else r = mid - 1 ;
        }

        printf("%d\n" , s) ;
    }
    return 0;
}

你可能感兴趣的:(fzu2233 2-sat)