POJ 2749 二分+2-sat判定

来源:互联网 发布:萌猫闹钟软件 编辑:程序博客网 时间:2024/06/06 04:27

这题还是挺好想建图的 二分判定就行了


#include <iostream>#include <cstdio>#include <cstring>#include <algorithm>#include <vector>#include <stack>#include <queue>#define MAXN 2005#define MAXM 50005#define INF 1000000000using namespace std;vector<int>g[MAXN];int n, A, B;int hatex[MAXN], hatey[MAXN], frix[MAXN], friy[MAXN];int scc, index;int low[MAXN], dfn[MAXN], instack[MAXN], fa[MAXN];stack<int>st;struct P{    int x, y;}s1, s2, p[MAXN];void init(){    for(int i = 0; i < MAXN; i++) g[i].clear();    memset(dfn, 0, sizeof(dfn));    while(!st.empty()) st.pop();    memset(instack, 0, sizeof(instack));    scc = index = 0;}void tarjan(int u){    dfn[u] = low[u] = ++index;    instack[u] = 1;    st.push(u);    int v;    int size = g[u].size();    for(int i = 0; i < size; i++)    {        v = g[u][i];        if(!dfn[v])        {            tarjan(v);            low[u] = min(low[u], low[v]);        }        else if(instack[v]) low[u] = min(low[u], dfn[v]);    }    if(dfn[u] == low[u])    {        scc++;        do        {            v = st.top();            st.pop();            fa[v] = scc;            instack[v] = 0;        }while(v != u);    }}int dist(P a, P b){    return abs(a.x - b.x) + abs(a.y - b.y);}void build(int mid){    for(int i = 1; i <= n; i++)        for(int j = i + 1; j <= n; j++)        {            if(dist(p[i], s1) + dist(p[j], s1) > mid)            {                g[i].push_back(j + n);                g[j].push_back(i + n);            }            if(dist(p[i], s2) + dist(p[j], s2) > mid)            {                g[i + n].push_back(j);                g[j + n].push_back(i);            }            if(dist(s1, s2) + dist(p[i], s1) + dist(p[j], s2) > mid)            {                g[i].push_back(j);                g[j + n].push_back(i + n);            }            if(dist(s1, s2) + dist(p[i], s2) + dist(p[j], s1) > mid)            {                g[i + n].push_back(j + n);                g[j].push_back(i);            }        }    for(int i = 1; i <= A; i++)    {        g[hatex[i]].push_back(hatey[i] + n);        g[hatey[i]].push_back(hatex[i] + n);        g[hatex[i] + n].push_back(hatey[i]);        g[hatey[i] + n].push_back(hatex[i]);    }    for(int i = 1; i <= B; i++)    {        g[frix[i]].push_back(friy[i]);        g[frix[i] + n].push_back(friy[i] + n);        g[friy[i]].push_back(frix[i]);        g[friy[i] + n].push_back(frix[i] + n);    }}bool check(){    for(int i = 1; i <= 2 * n; i++)        if(!dfn[i]) tarjan(i);    for(int i = 1; i <= n; i++)        if(fa[i] == fa[i + n]) return false;    return true;}void solve(){    int low = 0, high = INF, ans = INF;    while(low <= high)    {        int mid = (low + high) >> 1;        init();        build(mid);        if(check()) {high = mid - 1; ans = min(ans, mid);}        else low = mid + 1;    }    if(ans != INF)    printf("%d\n", ans);    else puts("-1");}int main(){    while(scanf("%d%d%d", &n, &A, &B) != EOF)    {        scanf("%d%d%d%d", &s1.x, &s1.y, &s2.x, &s2.y);        for(int i = 1; i <= n; i++) scanf("%d%d", &p[i].x, &p[i].y);        for(int i = 1; i <= A; i++) scanf("%d%d", &hatex[i], &hatey[i]);        for(int i = 1; i <= B; i++) scanf("%d%d", &frix[i], &friy[i]);        solve();    }    return 0;}


原创粉丝点击