一个菜菜的蜕变之路?

时间是个常数,也是个变数

Poj P3207 Ikki's Story IV - Panda's Trick___2-SAT

题目大意:

在圆上有N,有M个要求Ai,Bi,要求满足点Ai,Bi之间在圆内或者圆外存在一条连边,问是否存在一种边的分配方案使得任意两边之间不相交。

n1,000,m500

分析:

显然一条边A与边B在圆内相交,
那么显然它们在圆外也会相交
那么我们对于一条边i而言,
显然有二种选择,圆内或圆外,就可以转化成一个2SAT的模型。

当边i与边j在圆内相交,
那么显然它们必须要一个在圆内一个在圆外才能满足不冲突

则连边:
i>j
j>i
i>j
j>i
然后通过强联通分量判断即可

代码:

#include<algorithm>
#include<iostream>  
#include<cstring>  
#include<cstdio>
#include<stack>  
#define N 1000005
#define M 505

using namespace std;  

struct Edge{  
    int u, v, next;  
}a[N];  

int Ls[N], instack[N], dfn[N], low[N], belong[N], px[M], py[M];  
int n, m, tot, num, cnt;

void addedge(int u, int v){  
    ++tot;
    a[tot].u = u; a[tot].v = v; 
    a[tot].next = Ls[u];  Ls[u]=tot;  
}  

stack <int>st;  

void tarjan(int u) { 
    dfn[u] = low[u] = ++num;  
    instack[u] = 1;  
    st.push(u);  
    for (int i = Ls[u]; i; i = a[i].next) {   
         int v = a[i].v;  
         if (!dfn[v]){  
             tarjan(v);  
             low[u] = min(low[u], low[v]);  
         }  
         else if (instack[v]) low[u] = min(low[u], dfn[v]);  
    }  

    if (low[u] == dfn[u]) {  
         cnt++;
         int rp;
         while ("rp++") {
                rp = st.top(); 
                st.pop();  
                instack[rp] = 0;  
                belong[rp] = cnt;  
                if (rp == u) break;
         } 
    }  
}  

void solve_problem() {    
    num = cnt = 0;  
    for (int i = 1; i <= 2 * m; i++) 
         instack[i] = belong[i] = dfn[i] = low[i] = 0;
    for (int i = 1; i <= 2 * m; i++)
         if (!dfn[i]) tarjan(i);  
}  

int main(){  
    while(~scanf("%d %d", &n, &m)){    
           for (int i = 1; i <= m; i++) {   
                scanf("%d %d", &px[i], &py[i]);  
                if (px[i] > py[i]) swap(px[i], py[i]);
           }  
           for (int i = 1; i <= 2 * m; i++) Ls[i] = 0;
           tot = 0;    
           for (int i = 1; i <= m; i++) {  
                for (int j = i + 1; j <= m; j++)   
                     if (px[j] >= px[i] && px[j] <= py[i] && py[j] >= py[i] || 
                         py[j] >= px[i] && py[j] <= py[i] && px[j] <= px[i]) {  
                         addedge(i, j + m);
                         addedge(j, i + m);  
                         addedge(i + m, j);  
                         addedge(j + m, i);  
                     }      
           }
           solve_problem();  
           bool check = 1;  
           for (int i = 1; i <= m; i++)  
                if (belong[i] == belong[i+m]) check = 0;
           if (check) printf("panda is telling the truth...\n");  
                 else printf("the evil panda is lying again\n");  
    }
    return 0;  
}  
阅读更多
版权声明:欢迎借鉴,谢绝抄搬。 https://blog.csdn.net/Gx_Man_VIP/article/details/80394764
想对作者说点什么? 我来说一句

没有更多推荐了,返回首页

加入CSDN,享受更精准的内容推荐,与500万程序员共同成长!
关闭
关闭