|poj 2749|2-SAT|二分|Building roads

来源:互联网 发布:淘宝售假次数清零吗 编辑:程序博客网 时间:2024/05/21 19:25

poj传送门

/*    poj 2749    二分后2-SAT判断    本题教训:    1、加边视情况加    2、2-SAT里面的c在solve里面千万不要再int c */#include<cstdio>#include<cstring>#include<vector>#include<cmath>#include<algorithm>#define ll long long#define db double#define ms(i,j) memset(i,j)#define INF 100000000#define llINF 1LL<<60using namespace std;const int MAXN = (50000 + 5) * 2, LEFT = 0, RIGHT = 1;struct TwoSAT{    vector<int> G[MAXN*2];    int mark[MAXN*2];    int S[MAXN*2];    int n, c;    void init(int n)    {        this->n = n;        for (int i=0;i<=n*2;i++)        {            mark[i] = false;            G[i].clear();        }    }    void addE(int x, int xv, int y, int yv)    {        x = x*2 + xv;        y = y*2 + yv;        G[x^1].push_back(y);        G[y^1].push_back(x);    }    int dfs(int x)    {        if (mark[x^1]) return false;        if (mark[x]) return true;        mark[x] = true;        S[c++] = x;        for (int i=0;i<G[x].size();i++)        {            if (!dfs(G[x][i])) return false;        }        return true;    }    bool solve()    {        for (int i = 0;i < n;i += 2)        if (!mark[i]&&!mark[i+1])        {            c = 0;            if (!dfs(i))            {                for (int j = 0; j < c; j++)                        mark[S[j]] = false;                    c = 0;                if (!dfs(i+1)) return false;            }        }        return true;    }}ts;int n, A, B, sx1, sy1, sx2, sy2, xi[MAXN], yi[MAXN], hate[MAXN][2], fri[MAXN][2], d1[MAXN], d2[MAXN],di;int dis(int x1, int y1, int x2, int y2){    return abs(x1-x2)+abs(y1-y2);}int judge(int mid){    ts.init(n);    for (int i=0;i<n;i++)    for (int j=i+1;j<n;j++)    {        int x = i, y = j;        if (d1[i]+d1[j]>mid)    ts.addE(x, 1, y, 1);        if (d2[i]+d2[j]>mid)    ts.addE(x, 0, y, 0);        if (d1[i]+di+d2[j]>mid) ts.addE(x, 1, y, 0);        if (d2[i]+di+d1[j]>mid) ts.addE(x, 0, y, 1);    }    for (int i=0;i<A;i++)    {        int x = hate[i][LEFT] - 1, y = hate[i][RIGHT] - 1;        ts.addE(x, 0, y, 0);        ts.addE(x, 1, y, 1);    }    for (int i=0;i<B;i++)    {        int x = fri[i][LEFT] - 1, y = fri[i][RIGHT] - 1;        ts.addE(x, 0, y, 1);        ts.addE(y, 0, x, 1);    }    return ts.solve();}int init(){    scanf("%d%d%d%d", &sx1, &sy1, &sx2, &sy2);    for (int i=0;i<n;i++)    {        scanf("%d%d", &xi[i], &yi[i]);    }    for (int i=0;i<A;i++)    {        scanf("%d%d", &hate[i][LEFT], &hate[i][RIGHT]);    }    for (int i=0;i<B;i++)    {        scanf("%d%d", &fri[i][LEFT], &fri[i][RIGHT]);    }}int solve(){    di = dis(sx1, sy1, sx2, sy2);    for (int i=0;i<n;i++)    {        d1[i] = dis(xi[i], yi[i], sx1, sy1);        d2[i] = dis(xi[i], yi[i], sx2, sy2);    }    int l = 0, r = 8000000, ans = 10000000;    while (l < r)    {        int mid = (l + r) / 2;        if (judge(mid))        {            ans = mid;            r = mid;        } else l = mid+1;    }    if (ans!=10000000)    {        printf("%d\n", ans);    } else printf("%d\n", -1);}int main(){    while (scanf("%d%d%d", &n, &A, &B)==3)    {        init();        solve();    }    return 0;}
0 0
原创粉丝点击