POJ 2749

二分+2SAT的题

写错了HIGH和LOW与MID的变换,TLE了好几次。。

按HATE和LIKE关系先加边,再用距离的限制加边。

dist(i,S1)+dist(S1,j)>limit  Xi->~Xj  Xj->Xi

dist(i,S2)+dist(S2,j)>limit  ~Xi->Xj  ~Xj->Xi

dist(i,S1)+dist(S1,S2)+dist(S2,j)>limit Xi->Xj  ~Xj->~Xi

dist(i,S2)+dist(S2,S1)+dist(S1,j)>limit ~Xi->~Xj  Xj->Xi

用离散数学的知识就能推出来,以上借别人的一用。

  1 #include <iostream>
  2 #include <cstdio>
  3 #include <cstring>
  4 #include <algorithm>
  5 #include <cmath>
  6
  7 using namespace std;
  8
  9 const int inf=8500000;
 10 const int MAXN=1050;
 11 const int MAXM=20000000;
 12 int s1_s2,dis1[MAXN],dis2[MAXN],head[MAXN],dfn[MAXN],low[MAXN],belong[MAXN];
 13 int st[MAXN],stop,indx,tot,pat;
 14 bool stack[MAXN]; int leng;
 15 int n,hn,ln;
 16 struct d{
 17     int x,y;
 18 }point[MAXN],s1,s2;
 19 struct h{
 20     int u,v;
 21 }hate[MAXN*2];
 22 struct l{
 23     int u,v;
 24 }like[MAXN*2];
 25
 26 struct ei{
 27     int u,v;
 28     int next;
 29 }edge[MAXM];
 30
 31 void addedge(int u,int v){
 32     edge[tot].u=u;
 33     edge[tot].v=v;
 34     edge[tot].next=head[u];
 35     head[u]=tot++;
 36 }
 37
 38 void tarjan(int u){
 39     int v;
 40     dfn[u]=low[u]=++indx;
 41     st[stop++]=u;
 42     stack[u]=true;
 43     for(int e=head[u];e!=-1;e=edge[e].next){
 44         v=edge[e].v;
 45         if(dfn[v]==0){
 46             tarjan(v);
 47             low[u]=min(low[u],low[v]);
 48         }
 49         else if(stack[v]){
 50             low[u]=min(low[u],dfn[v]);
 51         }
 52     }
 53     if(dfn[u]==low[u]){
 54         pat++;
 55         do{
 56             v=st[--stop];
 57             stack[v]=false;
 58             belong[v]=pat;
 59         }while(u!=v);
 60     }
 61 }
 62
 63 bool slove(){
 64     int u,v;
 65
 66     memset(head,-1,sizeof(head));
 67     memset(dfn,0,sizeof(dfn));
 68     memset(low,0,sizeof(low));
 69     memset(belong,0,sizeof(belong));
 70     stop=0; indx=0; tot=0; pat=0;
 71     memset(stack,false,sizeof(stack));
 72
 73
 74     for(int i=0;i<hn;i++){
 75         u=hate[i].u;
 76         v=hate[i].v;
 77         addedge(u*2,v*2+1);
 78         addedge(v*2,u*2+1);
 79         addedge(2*u+1,2*v);
 80         addedge(2*v+1,2*u);
 81     }
 82     for(int i=0;i<ln;i++){
 83         u=like[i].u;
 84         v=like[i].v;
 85         addedge(u*2,v*2);
 86         addedge(v*2,u*2);
 87         addedge(2*u+1,2*v+1);
 88         addedge(2*v+1,2*u+1);
 89     }
 90     for(int i=0;i<n;i++){
 91         for(int j=i+1;j<n;j++){
 92             if(dis1[i]+dis1[j]>leng){
 93                 addedge(i*2,j*2+1);
 94                 addedge(j*2,i*2+1);
 95             }
 96             if(dis2[i]+dis2[j]>leng){
 97                 addedge(i*2+1,j*2);
 98                 addedge(j*2+1,i*2);
 99             }
100             if(dis1[i]+s1_s2+dis2[j]>leng){
101                 addedge(i*2,j*2);
102                 addedge(j*2+1,i*2+1);
103             }
104             if(dis2[i]+s1_s2+dis1[j]>leng){
105                 addedge(j*2,i*2);
106                 addedge(i*2+1,j*2+1);
107             }
108         }
109     }
110     for(int i=0;i<2*n;i++){
111         if(dfn[i]==0)
112         tarjan(i);
113     }
114     bool flag=true;
115     for(int i=0;i<n;i++){
116         if(belong[2*i]==belong[2*i+1]){
117             flag=false;
118             break;
119         }
120     }
121     return flag;
122 }
123
124 int main(){
125     int u,v; int tmp;
126     while(scanf("%d%d%d",&n,&hn,&ln)!=EOF){
127         scanf("%d%d%d%d",&s1.x,&s1.y,&s2.x,&s2.y);
128         for(int i=0;i<n;i++){
129         scanf("%d%d",&point[i].x,&point[i].y);
130         }
131         for(int i=0;i<hn;i++){
132             scanf("%d%d",&u,&v);
133             u--; v--;
134             hate[i].u=u; hate[i].v=v;
135         }
136         for(int i=0;i<ln;i++){
137             scanf("%d%d",&u,&v);
138             u--; v--;
139             like[i].u=u; like[i].v=v;
140         }
141         for(int i=0;i<n;i++){
142             tmp=abs(point[i].x-s1.x)+abs(point[i].y-s1.y);
143             dis1[i]=tmp;
144             tmp=abs(point[i].x-s2.x)+abs(point[i].y-s2.y);
145             dis2[i]=tmp;
146         }
147         s1_s2=abs(s1.x-s2.x)+abs(s1.y-s2.y);
148         int lown=1,high=inf,ans=-1;
149         while(lown<=high){
150             int mid=(lown+high)/2;
151             leng=mid;
152             if(slove()){
153                 ans=mid;
154                 high=mid-1;
155             }
156             else lown=mid+1;
157         }
158         printf("%d\n",ans);
159     }
160     return 0;
161 }

POJ 2749

时间: 2024-10-29 19:12:16

POJ 2749的相关文章

poj 2749 Building roads 2-sat

题意: 给n个村庄的坐标和两个特殊点s1,s2的坐标,现在要将每个村庄连到s1或s2上,使n个村庄间的最大距离最小. 分析: 二分任意两村庄间的最大距离,用2-sat判断该最大距离是否可行,二分的时候可以顺便记录答案,不用等最后区间为空时再输出l或l-1. 代码: //poj 2749 //sep9 #include <iostream> #include <vector> using namespace std; const int maxN=1024; const int ma

HDU 1815, POJ 2749 Building roads(2-sat)

HDU 1815, POJ 2749 Building roads 题目链接HDU 题目链接POJ 题意: 有n个牛棚, 还有两个中转站S1和S2, S1和S2用一条路连接起来. 为了使得任意牛棚两个都可以有道路联通,现在要让每个牛棚都连接一条路到S1或者S2. 有a对牛棚互相有仇恨,所以不能让他们的路连接到同一个中转站.还有b对牛棚互相喜欢,所以他们的路必须连到同一个中专站. 道路的长度是两点的曼哈顿距离. 问最小的任意两牛棚间的距离中的最大值是多少? 思路:二分距离,考虑每两个牛棚之间4种连

poj 2749 Building roads (二分+拆点+2-sat)

Building roads Time Limit: 2000MS   Memory Limit: 65536K Total Submissions: 6229   Accepted: 2093 Description Farmer John's farm has N barns, and there are some cows that live in each barn. The cows like to drop around, so John wants to build some ro

poj 2749 Building roads(2-sat)

Description Farmer John's farm has N barns, and there are some cows that live in each barn. The cows like to drop around, so John wants to build some roads to connect these barns. If he builds roads for every pair of different barns, then he must bui

POJ 2749 Building roads 2-sat+二分答案

把爱恨和最大距离视为限制条件,可以知道,最大距离和限制条件多少具有单调性 所以可以二分最大距离,加边+check 1 #include<cstdio> 2 #include<algorithm> 3 #include<cstring> 4 #include<vector> 5 #include<stack> 6 #define N 5010 7 #define INF 4000000 8 using namespace std; 9 int di

[poj] 2749 building roads

原题 2-SAT+二分答案! 最小的最大值,这肯定是二分答案.而我们要2-SATcheck是否在该情况下有可行解. 对于目前的答案limit,首先把爱和恨连边,然后我们n^2枚举每两个点通过判断距离来实现连边,然后跑2-SAT判断是否有可行解 O(n^2logn) 想起来和听起来都很难写,事实上还好吧- #include<cstdio> #include<algorithm> #include<stack> #include<cstring> #define

图论常用算法之一 POJ图论题集【转载】

POJ图论分类[转] 一个很不错的图论分类,非常感谢原版的作者!!!在这里分享给大家,爱好图论的ACMer不寂寞了... (很抱歉没有找到此题集整理的原创作者,感谢知情的朋友给个原创链接) POJ:http://poj.org/ 1062* 昂贵的聘礼 枚举等级限制+dijkstra 1087* A Plug for UNIX 2分匹配 1094 Sorting It All Out floyd 或 拓扑 1112* Team Them Up! 2分图染色+DP 1125 Stockbroker

[转] 一些图论、网络流入门题总结、汇总

最短路问题此类问题类型不多,变形较少 POJ 2449 Remmarguts' Date(中等)http://acm.pku.edu.cn/JudgeOnline/problem?id=2449题意:经典问题:K短路解法:dijkstra+A*(rec),方法很多相关:http://acm.pku.edu.cn/JudgeOnline/showcontest?contest_id=1144该题亦放在搜索推荐题中 POJ 3013 - Big Christmas Tree(基础)http://ac

【转】一些图论、网络流入门题总结、汇总

最短路问题 此类问题类型不多,变形较少 POJ 2449 Remmarguts' Date(中等) http://acm.pku.edu.cn/JudgeOnline/problem?id=2449 题意:经典问题:K短路 解法:dijkstra+A*(rec),方法很多 相关:http://acm.pku.edu.cn/JudgeOnline/showcontest?contest_id=1144 该题亦放在搜索推荐题中 POJ 3013 - Big Christmas Tree(基础) ht