POJ 2296 & POJ 3678

POJ 2296与POJ 3678建图有一个地方要注意,即类似 a && b == 1,则a和b都必须为1,那么需要添加两条边~a->a,~b->b。

 

POJ 2296有一种情况是必须加边的,即:两个矩形的坐标差不超过边长时,只可能一种情况,就是一个在上,一个在下,那么就需用到上述的加边。

 

POJ 2296:

#include <iostream>
#include <cstdlib>
#include <cstdio>
#include <string>
#include <cstring>
#include <cmath>
#include <vector>
#include <queue>
#include <algorithm>
#include <map>
using namespace std;

const int maxn = 210;
const int maxm = 210*210*5;
const int INF = 0x3f3f3f3f;

struct Edge
{
    int v, w;
    int next;
}edge[maxm];

int first[maxn], stack[maxn], ins[maxn], dfn[maxn], low[maxn];
int belong[maxn];

int n, m;
int cnt;
int scnt, top, tot;

void init()
{
    cnt = 0;
    scnt = top = tot = 0;
    memset(first, -1, sizeof(first));
    memset(dfn, 0, sizeof(dfn));
    memset(ins, 0, sizeof(ins));
    memset(low, 0, sizeof(low));
}

void read_graph(int u, int v)
{
    edge[cnt].v = v;
    edge[cnt].next = first[u], first[u] = cnt++;
}

void dfs(int u)
{
    int v;
    low[u] = dfn[u] = ++tot;
    stack[top++] = u;
    ins[u] = 1;
    for(int e = first[u]; e != -1; e = edge[e].next)
    {
        v = edge[e].v;
        if(!dfn[v]) { dfs(v); low[u] = min(low[u], low[v]); }
        else if(ins[v]) { low[u] = min(low[u], dfn[v]); }
    }
    if(low[u] == dfn[u])
    {
        scnt++;
        do { v = stack[--top]; belong[v] = scnt; ins[v] = 0; } while(u != v);
    }
}

void Tarjan()
{
    for(int v = 0; v < 2*n; v++) if(!dfn[v])
        dfs(v);
}

void readint(int &x)
{
    char c;
    while(!isdigit(c)) c = getchar();
    
    x = 0;
    while(isdigit(c))
    {
        x = x*10 + c-'0';
        c = getchar();
    }
}

void writeint(int x)
{
    if(x > 9) writeint(x/10);
    putchar(x%10+'0');
}

struct Point
{
    int x, y;
    
    Point() {}
    Point(int x, int y): x(x), y(y) {}
}P[maxn];

void read_case()
{
    init();
    readint(n);
    for(int i = 0; i < n; i++)
    {
        int x, y;
        scanf("%d%d", &x, &y);
        P[i] = Point(x, y);
    }
}

void build(int mid)
{
    init();
    
    for(int i = 0; i < n; i++)
    for(int j = 0; j < n; j++) if(i != j)
    {
        if(abs(P[i].x-P[j].x) < mid)
        {
            int dif = P[i].y - P[j].y;
            
            if(dif < 2*mid && dif >= mid)
            {
                read_graph(i+n, j+n);
            }
            else if(dif > 0 && dif < mid) //i为必选,那么连一条边~i->i 
            {
                read_graph(i+n, i);
            }
            else if(dif == 0)
            {
                read_graph(i, j+n);
                read_graph(i+n, j);
            }
            else if(dif < 0 && dif > -mid)
            {
                read_graph(i, i+n);
            }
            else if(dif <= -mid && dif > -2*mid)
            {
                read_graph(i, j);
            }
        }
    }
    
    Tarjan();
}

int ok()
{
    for(int i = 0; i < n; i++) if(belong[i] == belong[i+n]) return 0;
    return 1;
}

int BSearch(int x, int y)
{
    int ans = -1;
    while(x <= y)
    {
        int mid = x+(y-x)/2;
        build(mid);
        
        if(ok()) { ans = mid; x = mid+1; }
        else y = mid-1;
    }
    return ans;
}

void solve()
{
    read_case();
    
    int ans = BSearch(0, 20010);
    writeint(ans), puts("");
}

int main()
{
    int T;
    for(readint(T); T--; ) solve();
    return 0;
}
View Code

 

POJ 3678

#include <iostream>
#include <cstdlib>
#include <cstdio>
#include <string>
#include <cstring>
#include <cmath>
#include <vector>
#include <queue>
#include <algorithm>
#include <map>
using namespace std;

const int maxn = 2010;
const int maxm = 1010*1010*5;
const int INF = 0x3f3f3f3f;

struct Edge
{
    int v, w;
    int next;
    int id;
}edge[maxm];

int first[maxn], stack[maxn], ins[maxn], dfn[maxn], low[maxn];
int belong[maxn];

int n, m;
int cnt;
int scnt, top, tot;

void init()
{
    cnt = 0;
    scnt = top = tot = 0;
    memset(first, -1, sizeof(first));
    memset(dfn, 0, sizeof(dfn));
    memset(ins, 0, sizeof(ins));
    memset(low, 0, sizeof(low));
}

void read_graph(int u, int v)
{
    edge[cnt].v = v;
    edge[cnt].next = first[u], first[u] = cnt++;
}

void dfs(int u)
{
    int v;
    low[u] = dfn[u] = ++tot;
    stack[top++] = u;
    ins[u] = 1;
    for(int e = first[u]; e != -1; e = edge[e].next)
    {
        v = edge[e].v;
        if(!dfn[v]) { dfs(v); low[u] = min(low[u], low[v]); }
        else if(ins[v]) { low[u] = min(low[u], dfn[v]); }
    }
    if(low[u] == dfn[u])
    {
        scnt++;
        do { v = stack[--top]; belong[v] = scnt; ins[v] = 0; } while(u != v);
    }
}

void Tarjan()
{
    for(int v = 0; v < 2*n; v++) if(!dfn[v])
        dfs(v);
}

void readint(int &x)
{
    char c;
    while(!isdigit(c)) c = getchar();
    
    x = 0;
    while(isdigit(c))
    {
        x = x*10 + c-'0';
        c = getchar();
    }
}

void writeint(int x)
{
    if(x > 9) writeint(x/10);
    putchar(x%10+'0');
}

void read_case()
{
    init();
    
    char op[10];
    
    while(m--)
    {
        int x, y, z;
        scanf("%d%d%d%s", &x, &y, &z, &op);
        
        if(op[0] == 'A')
        {
            if(z)
            {
                read_graph(x, x+n);
                read_graph(y, y+n);
            }
            else
            {
                read_graph(x+n, y);
                read_graph(y+n, x);
            }
        }
        else if(op[0] == 'O')
        {
            if(z)
            {
                read_graph(x, y+n);
                read_graph(y, x+n);
            }
            else
            {
                read_graph(x+n, x);
                read_graph(y+n, y);
            }
        }
        else if(op[0] == 'X')
        {
            if(z)
            {
                read_graph(x, y+n), read_graph(x+n, y);
                read_graph(y, x+n), read_graph(y+n, x);
            }
            else
            {
                read_graph(x, y), read_graph(y, x);
                read_graph(x+n, y+n), read_graph(y+n, x+n);
            }
        }
    }
}

int ok()
{
    for(int i = 0; i < n; i++) if(belong[i] == belong[i+n]) return 0;
    return 1;
}

void solve()
{
    read_case();
    
    Tarjan();
    if(ok()) printf("YES
");
    else printf("NO
");
}

int main()
{
    while(~scanf("%d%d", &n, &m))
    {
        solve();
    }
    return 0;
}
View Code

 特殊的连边方式: http://blog.sina.com.cn/s/blog_68629c7701010gf1.html

原文地址:https://www.cnblogs.com/Buck-Meister/p/3139060.html