• poj3207-Ikki's Story IV


    (n)个数字按顺序排成一圈,给出(m)条连线((a,b)),连线可以在圆内或圆外,问是否可能做到所有连线只在顶点上相交。

    分析

    一个好像平面图判定的题~

    两条线((a,b))((c,d))相交的条件是(a<c<b<d),如果他们在圆内会相交,那么他们在圆外也会相交,也就是说,这两条线是不能同时在圆内或圆外的。一条线在圆内或圆外,有两种取值,可以看成是一个2-SAT问题。发现数据范围不大,所以直接对所有的连线两两判定一下,连边表示他们不共存就好了。注意不共存的连边是(a e b),等价于(aoplus b=true)

    其实这个题还可以用二分图染色做。观察上面的连边,可以发现,这里的条件都是某两条线的不共存,所以我们可以把圆内和圆外看成二分图的左边和右边,不共存的连边,然后只要判断这个图是不是一个二分图即可。

    代码

    2-SAT

    #include<cstdio>
    #include<algorithm>
    #include<cctype>
    #include<cstring>
    using namespace std;
    int read() {
    	int x=0,f=1;
    	char c=getchar();
    	for (;!isdigit(c);c=getchar()) if (c=='-') f=-1;
    	for (;isdigit(c);c=getchar()) x=x*10+c-'0';
    	return x*f;
    }
    const int maxn=1005;
    const int maxm=maxn*maxn;
    int dfn[maxn],low[maxn],id[maxn],dft=0,sta[maxn],top=0,col=0;
    bool ins[maxn];
    struct line {
    	int x,y;
    	void sort() {
    		if (x>y) swap(x,y);
    	}
    } a[maxn];
    bool cross(line &a,line &b) {
    	return a.x<b.x && b.x<a.y && a.y<b.y;
    }
    struct edge {
    	int v,nxt;
    };
    struct graph {
    	edge e[maxm];
    	int h[maxn],tot;
    	graph ():tot(0) {}
    	void add(int u,int v) {
    		e[++tot]=(edge){v,h[u]};
    		h[u]=tot;
    	}
    	void Tarjan(int x) {
    		dfn[x]=low[x]=++dft;
    		sta[++top]=x;
    		ins[x]=true;
    		for (int i=h[x],v=e[i].v;i;i=e[i].nxt,v=e[i].v) if (!dfn[v]) {
    			Tarjan(v);
    			low[x]=min(low[x],low[v]);
    		} else if (ins[v]) low[x]=min(low[x],dfn[v]);
    		if (low[x]==dfn[x]) {
    			++col;
    			do id[sta[top--]]=col; while (sta[top+1]!=x);
    		}
    		ins[x]=false;
    	}
    	bool run(int m) {
    		for (int i=1;i<=m;++i) if (id[i]==id[i+m]) return false;
    		return true;
    	}
    } A;
    int main() {
    #ifndef ONLINE_JUDGE
    	freopen("test.in","r",stdin);
    #endif
    	int n=read(),m=read();
    	for (int i=1;i<=m;++i) a[i].x=read(),a[i].y=read(),a[i].sort();
    	for (int i=1;i<=m;++i) for (int j=i+1;j<=m;++j) if (cross(a[i],a[j])) {
    		A.add(i,j+m),A.add(j,i+m),A.add(i+m,j),A.add(j+m,i);
    	}
    	for (int i=1;i<=(m<<1);++i) if (!dfn[i]) A.Tarjan(i);
    	puts(A.run(m)?"panda is telling the truth...":"the evil panda is lying again");
    	return 0;
    }
    

    二分图染色

    #include<cstdio>
    #include<algorithm>
    #include<cctype>
    #include<cstring>
    using namespace std;
    int read() {
    	int x=0,f=1;
    	char c=getchar();
    	for (;!isdigit(c);c=getchar()) if (c=='-') f=-1;
    	for (;isdigit(c);c=getchar()) x=x*10+c-'0';
    	return x*f;
    }
    const int maxn=1005;
    const int maxm=maxn*maxn;
    int col[maxn];
    bool flag=true;
    struct line {
    	int x,y;
    	void sort() {
    		if (x>y) swap(x,y);
    	}
    } a[maxn];
    bool cross(line &a,line &b) {
    	return a.x<b.x && b.x<a.y && a.y<b.y;
    }
    struct edge {
    	int v,nxt;
    };
    struct graph {
    	edge e[maxm];
    	int h[maxn],tot;
    	graph ():tot(0) {}
    	void add(int u,int v) {
    		e[++tot]=(edge){v,h[u]};
    		h[u]=tot;
    	}
    	bool dye(int x,int c) {
    		col[x]=c;
    		for (int i=h[x],v=e[i].v;i;i=e[i].nxt,v=e[i].v) {
    			if (col[v]==(c^1)) continue;
    			if (col[v]==c) return false;
    			if (!dye(v,c^1)) return false;
    		} 
    		return true;
    	}
    } A;
    int main() {
    #ifndef ONLINE_JUDGE
    	freopen("test.in","r",stdin);
    #endif
    	int n=read(),m=read();
    	for (int i=1;i<=m;++i) a[i].x=read(),a[i].y=read(),a[i].sort();
    	for (int i=1;i<=m;++i) for (int j=i+1;j<=m;++j) if (cross(a[i],a[j])) A.add(i,j),A.add(j,i);
    	for (int i=1;i<=m;++i) if (!col[i] && !A.dye(i,2)) {
    		flag=false;
    		break;
    	}
    	puts(flag?"panda is telling the truth...":"the evil panda is lying again");
    	return 0;
    }
    
  • 相关阅读:
    #454. 【UER #8】打雪仗
    6496. 【GDOI2020模拟03.08】圣痕
    6495. 【GDOI2020模拟03.08】死星
    6494. 【GDOI2020模拟03.08】勘探
    NOI Online划水记
    6482. 【GDOI2020模拟02.22】代数几何(algebraic)
    6493. 【GDOI2020模拟03.04】迷宫
    6492. 【GDOI2020模拟03.04】多项式
    6491. 【GDOI2020模拟03.04】铺路
    #76. 【UR #6】懒癌
  • 原文地址:https://www.cnblogs.com/owenyu/p/6741754.html
Copyright © 2020-2023  润新知