Codeforces Beta Round #27 D. Ring Road 2

题意:有一个环,现给你一些区间的起点与终点,区间可以在环内,可以在环外,但是在环内环外的区间都不能彼此相交,问可能否,如果可能,输出方案。

2-SAT。

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

typedef long long LL;
typedef pair<int,int> PII;

const int N=205;
const int MaxN=11005;
const int MaxE=51005;

struct Edge
{
    int u,v,pre;
    Edge(){}
    Edge(int u,int v,int pre) :
        u(u),v(v),pre(pre) {}
}edge[N*10];

int hBef[N],hAft[N],nEdge;

int n,m,L[N],R[N];
bool insta[MaxN];
int lab[MaxN],nLab;
int sta[MaxN],top;
int dfn[MaxN],low[MaxN],idx;
int deg[MaxN],color[MaxN],other[MaxN];

struct Tarjan_directed
{
	void init()
	{
		nLab=top=idx=0;
		memset(lab,-1,sizeof(lab));
		memset(dfn,0,sizeof(dfn));
		memset(low,0,sizeof(low));
		memset(insta,0,sizeof(insta));
		memset(deg,0,sizeof(deg));
	}

	void dfs(int u)
	{
		insta[u]=1;
		sta[top++]=u;
		dfn[u]=low[u]=++idx;
		for(int i=hBef[u];i!=-1;i=edge[i].pre)
		{
			int v=edge[i].v;
			if(!dfn[v])
			{
				dfs(v);
				low[u]=min(low[u],low[v]);
			}
			else if(insta[v]&&dfn[v]<low[u]) low[u]=dfn[v];
		}

		if(low[u]==dfn[u])
		{
			++nLab; int tmp;
			do
			{
				tmp=sta[--top];
				insta[tmp]=0;
				lab[tmp]=nLab;
			}while(tmp!=u);
		}
	}
	void solve()
	{
	    for(int i=0;i<n*2;i++)  if(dfn[i]==0) dfs(i);
	}
}tar;

void addEdge(int u,int v,int head[])
{
    edge[nEdge]=Edge(u,v,head[u]);
    head[u]=nEdge++;
}
void edgeInit()
{
    nEdge=0;
    memset(hBef,-1,sizeof(hBef));
    memset(hAft,-1,sizeof(hAft));
}

bool Intersect(int L1,int R1,int L2,int R2)
{
    if(L1>L2) swap(L1,L2),swap(R1,R2);
    if(L1==L2&&R1<R2) swap(L1,L2),swap(R1,R2);

    if(R1<=L2) return false;
    if(R2<=R1) return false;
    return true;
}
void BuildGraph()
{
    for(int i=0;i<n;i++)
    {
        for(int j=i+1;j<n;j++) if(Intersect(L[i],R[i],L[j],R[j]))
        {
            addEdge(i,j+n,hBef);
            addEdge(j,i+n,hBef);
            addEdge(i+n,j,hBef);
            addEdge(j+n,i,hBef);
        }
    }
}
void RebuildGraph()
{
    int tmp=nEdge;
    for(int i=0;i<tmp;i++)
    {
        int u=lab[edge[i].u],v=lab[edge[i].v];
        if(u-v)
        {
            addEdge(v,u,hAft); deg[u]++;
        }
    }
}
bool HasAns()
{
    for(int i=0;i<n;i++)
    {
        int u=lab[i],v=lab[i+n];
        other[u]=v; other[v]=u;
        if(u==v)
        {
            puts("Impossible");
            return false;
        }
    }
    return true;
}
void TopSort()
{
    memset(color,0,sizeof(color));
    queue<int> que;

    for(int i=1;i<=nLab;i++) if(deg[i]==0) que.push(i);

    while(que.size())
    {
        int u=que.front(); que.pop();

        if(color[u]==0)
        {
            color[u]=1;
            color[other[u]]=2;
        }
        for(int i=hAft[u];i!=-1;i=edge[i].pre)
        {
            int v=edge[i].v;
            if(--deg[v]==0) que.push(v);
        }
    }
}
void OutputAns()
{
    for(int i=0;i<n;i++)
    {
        if(color[lab[i]]==1) putchar('i');
        else putchar('o');
    }
    puts("");
}
void TwoSAT()
{
    BuildGraph();
    tar.init(); tar.solve();
    if(HasAns()==0) return;
    RebuildGraph();
    TopSort();
    OutputAns();
}

int main()
{
    while(scanf("%d%d",&m,&n)!=EOF)
    {
        edgeInit();
        for(int i=0;i<n;i++)
        {
            scanf("%d%d",&L[i],&R[i]);
            if(L[i]>R[i]) swap(L[i],R[i]);
        }
        TwoSAT();
    }
	return 0;
}


你可能感兴趣的:(Codeforces Beta Round #27 D. Ring Road 2)