• POJ 2749--Building roads(2-SAT)


    两天总算刷完了这六题,也算是有些收获吧。

    先来说说建图的问题,之前我们可以看到都是建两条边,而这题得建四条边,为什么呢?

    因为根据实际情况考虑吧他们前后都有可能。

    所以在这里我们要得出结论,2-Sat题目就如同网络流,差分约束一样,根据题意给出的限制条件建图。

    然后再说说这个tarjan,作用是用来缩点,把一堆点变成一个,然后我sb的写的top+1那种,以后要注意这种写法的问题。

    对于输出一组解的题目呢,我们更要细心,时时刻刻心中默念自己i对应哪种状态,i+n对应哪种状态,然后1就是相同,0就是不同。

    其实如何看出这是一道2-Sat题目呢,我们首先要确定他初始状态即为两个对立状态,如一个在内一个在外,一个在左一个在右,然后再去找他们的对立状态,确定& | ^的关系,然后建图即可。

    By:大奕哥

      1 #include<iostream>
      2 #include<cstdlib>
      3 #include<cstdio>
      4 #include<algorithm>
      5 #include<cstring>
      6 #include<vector>
      7 #include<queue>
      8 using namespace std;
      9 const int N=5005;
     10 int ecnt,n,m,nn,top,num,cnt,slen,mi,ma,ans,a,b;
     11 int head[N],low[N],dfn[N],col[N],vis[N],ss[N];
     12 struct point{
     13     int a,b;
     14 }s[3],p[N],away[N],gay[N];
     15 inline int len(point a,point b){return abs(a.a-b.a)+abs(a.b-b.b);}
     16 struct edge
     17 {
     18     int to,nex;
     19 }e[1000005];
     20 void add(int x,int y)
     21 {
     22     e[++ecnt].to=y;e[ecnt].nex=head[x];head[x]=ecnt;
     23 }
     24 void init()
     25 {
     26     ecnt=cnt=num=top=0;
     27     memset(head,0,sizeof(head));
     28     memset(low,0,sizeof(low));
     29     memset(dfn,0,sizeof(dfn));
     30     memset(vis,0,sizeof(vis));
     31     memset(col,0,sizeof(col));
     32 }
     33 void dfs(int x)
     34 {
     35     vis[x]=1;ss[++top]=x;
     36     low[x]=dfn[x]=++cnt;
     37     for(int i=head[x];i;i=e[i].nex)
     38     {
     39         int y=e[i].to;
     40         if(!dfn[y])
     41         {
     42             dfs(y);
     43             low[x]=min(low[x],low[y]);
     44         }
     45         else if(vis[y])
     46         {
     47             low[x]=min(low[x],dfn[y]);
     48         }
     49     }
     50     if(low[x]==dfn[x])
     51     {
     52         num++;
     53         while(ss[top]!=x)
     54         {
     55             int a=ss[top--];
     56             vis[a]=0;
     57             col[a]=num;
     58         }
     59         int a=ss[top--];
     60         vis[a]=0;
     61         col[a]=num;
     62     }
     63     return;
     64 }
     65 bool judge(int mid)
     66 {
     67     init();
     68     for(int i=0;i<a;++i)
     69     {
     70         add(away[i].a+n,away[i].b);//1&1=1 都选后面 
     71         add(away[i].b+n,away[i].a);    
     72         
     73         add(away[i].a,away[i].b+n);//1&1=1 都选前面 
     74         add(away[i].b,away[i].a+n);
     75     }
     76     for(int i=0;i<b;++i)
     77     {
     78         add(gay[i].a,gay[i].b);//1&0=0 一前一后 
     79         add(gay[i].b+n,gay[i].a+n);    
     80         
     81         add(gay[i].a+n,gay[i].b+n);//0&1=0 一后一前 
     82         add(gay[i].b,gay[i].a);
     83     }
     84     for(int i=1;i<=n;++i)
     85     {
     86         for(int j=i+1;j<=n;++j)
     87         {
     88             if((len(p[i],s[0])+len(p[j],s[0]))>mid)add(i,j+n),add(j,i+n);
     89             if((len(p[i],s[1])+len(p[j],s[1]))>mid)add(i+n,j),add(j+n,i);
     90             if((len(p[i],s[0])+slen+len(p[j],s[1]))>mid)add(i,j),add(j+n,i+n);
     91             if((len(p[i],s[1])+slen+len(p[j],s[0]))>mid)add(i+n,j+n),add(j,i);        
     92         }
     93     }
     94     for(int i=1;i<=n*2;++i)
     95     if(!dfn[i])dfs(i);
     96     for(int i=1;i<=n;++i)
     97     {
     98         if(col[i]==col[i+n])return 0;
     99     }
    100     return 1;
    101 }
    102 
    103 int main()
    104 {
    105 //    freopen("1.out","r",stdin);
    106 //    freopen("my.out","w",stdout);
    107     scanf("%d%d%d",&n,&a,&b);
    108     scanf("%d%d%d%d",&s[0].a,&s[0].b,&s[1].a,&s[1].b);
    109     slen=len(s[1],s[0]);mi=1e9,ma=0;
    110     for(int i=1;i<=n;++i)
    111     {
    112         scanf("%d%d",&p[i].a,&p[i].b);
    113         mi=min(mi,min(len(p[i],s[0]),len(p[i],s[1])));
    114         ma=max(ma,max(len(p[i],s[0]),len(p[i],s[1])));
    115     }
    116     for(int i=0;i<a;++i)scanf("%d%d",&away[i].a,&away[i].b);
    117     for(int i=0;i<b;++i)scanf("%d%d",&gay[i].a,&gay[i].b);
    118     int l=mi*2,r=ma*2+slen,ans=-1;
    119     while(l<=r)
    120     {
    121         int mid=l+r>>1;
    122         if(judge(mid))r=mid-1,ans=mid;
    123         else l=mid+1;
    124     }
    125     printf("%d
    ",ans);
    126     return 0;
    127 }
  • 相关阅读:
    【splunk】数据输入-文件目录 导入失败
    【linux】tar压缩不包含路径
    【python】已安装模块提示ImportError: No module named
    【splunk】用正则表达式提取字段
    【python】xsspider零碎知识点
    【scrapy】资料
    【splunk】一些查询例子
    【docker】将容器中数据拷贝到主机
    【linux】ubuntu下crontab无效解决方法
    Flink – metrics V1.2
  • 原文地址:https://www.cnblogs.com/nbwzyzngyl/p/8312648.html
Copyright © 2020-2023  润新知