传送门

这道题真是2-SAT好题啊!!卡了我两个点才做完……垃圾POJ还不告诉我哪错了……

首先我们先花一段时间把题看懂……(其实是翻译一下),之后我们发现因为每个谷仓只能向一个中转点连边,所以他就是一个布尔变量的两个取值。然后对于每个限制条件,其实就是^嘛!我们把他转换为合取范式之后建一下图。不过怎么计算最大距离最小值呢?看到这一幕想起二分答案……然后,然后就不会了……

我们再想一下,其实2-SAT里面,每个给定的限制特别要命,因为如果要没有限制随便瞎取都能合法,然后我们要限制一个最大距离……那我们不妨把连接之后距离大于当前值的两个谷仓加一个限制,使两者不能连边,这样我们再跑一遍2-SAT判断一下当前是否合法,然后改变二分的值就可以。

具体怎么加距离的限制,如果两个点通过某种连接方式之后不合法,我们就把其中一个向另一个的否定连边(一个点连接s1,s2),比如说第一个点连向s1,第二个点连向s2,如果这样是不合法的情况的话,那么我们强制性让第一个点连s2,第二个点连s1,这样建边就可以啦。

然而说着容易做着难……代码贼拉难写+忘记判断-1+不知道怎么建边……卡了两个小时。

Source Code
Problem: User: ifvisit
Memory: 6176K Time: 1657MS
Language: C++ Result: Accepted Source Code #include<cstdio>
#include<algorithm>
#include<cstring>
#include<iostream>
#include<cmath>
#include<set>
#include<queue>
#define rep(i,a,n) for(int i = a;i <= n;i++)
#define per(i,n,a) for(int i = n;i >= a;i--)
#define fill(x,y) memset(x,y,sizeof(x));
#define enter putchar('\n') using namespace std;
typedef long long ll;
const int M = ;
const int N = ;
const int INF = ; int read()
{
int ans = ,op = ;
char ch = getchar();
while(ch < '' || ch > '')
{
if(ch == '-') op = -;
ch = getchar();
}
while(ch >= '' && ch <= '')
{
ans *= ;
ans += ch - '';
ch = getchar();
}
return ans * op;
} struct edge
{
int next,to,from;
}e[N]; struct node
{
int x,y;
}q[M]; struct relation
{
int a,b;
}ha[M],li[M]; int n,m,g,head[M],ecnt,dfn[M],low[M],stack[M],top,scc[M],a,b,c,d,dis1[M],dis2[M],len,idx,cnt;
int minn = ,maxn,ans;
int s1 = ,s2 = ;
bool vis[M]; void add(int x,int y)
{
e[++ecnt].to = y;
e[ecnt].from = x;
e[ecnt].next = head[x];
head[x] = ecnt;
}
int rev(int x)
{
return x > n ? x - n : x + n;
} int mht(int kx,int ky)
{
return abs(q[kx].x - q[ky].x) + abs(q[kx].y - q[ky].y);
} void clear()
{
memset(e,,sizeof(e));
memset(head,,sizeof(head));
memset(dfn,,sizeof(dfn));
memset(low,,sizeof(low));
memset(scc,,sizeof(scc));
ecnt = idx = cnt = ;
} void build(int x)
{
rep(i,,m)
{
int r1 = ha[i].a,r2 = ha[i].b;
add(r1,r2+n),add(r1+n,r2),add(r2,r1+n),add(r2+n,r1);
}
rep(i,,g)
{
int r1 = li[i].a,r2 = li[i].b;
add(r1,r2),add(r2,r1),add(r1+n,r2+n),add(r2+n,r1+n);
}
rep(i,,n)
{
rep(j,i+,n)
{
int l1 = dis1[i],l2 = dis2[i],r1 = dis1[j],r2 = dis2[j];
if(l1 + r1 > x) add(i,j+n),add(j,i+n);
if(l2 + r2 > x) add(i+n,j),add(j+n,i);
if(l1 + r2 + len > x) add(i,j),add(j+n,i+n);
if(l2 + r1 + len > x) add(i+n,j+n),add(j,i);
}
}
} void tarjan(int x)
{
dfn[x] = low[x] = ++idx;
stack[++top] = x,vis[x] = ;
for(int i = head[x];i;i = e[i].next)
{
if(!dfn[e[i].to]) tarjan(e[i].to),low[x] = min(low[x],low[e[i].to]);
else if(vis[e[i].to]) low[x] = min(low[x],dfn[e[i].to]);
}
if(low[x] == dfn[x])
{
int p;
cnt++;
while((p = stack[top--]))
{
scc[p] = cnt,vis[p] = ;
if(p == x) break;
}
}
} void solve()
{
int l = ,r = ;
while(l < r)
{
bool flag = ;
int mid = (l+r) >> ;
clear(),build(mid);
rep(i,,n<<) if(!dfn[i]) tarjan(i);
rep(i,,n)
{
if(scc[i] == scc[i+n])
{
flag = ;
break;
}
}
if(flag) l = mid + ;
else r = mid;
}
if(l == || l == ) printf("-1\n");
else printf("%d\n",l);
} int main()
{
n = read(),m = read(),g = read();
q[s1].x = read(),q[s1].y = read(),q[s2].x = read(),q[s2].y = read();
len = abs(q[s2].y-q[s1].y) + abs(q[s2].x-q[s1].x);
rep(i,,n)
{
q[i].x = read(),q[i].y = read();
dis1[i] = mht(i,s1),dis2[i] = mht(i,s2);
}
rep(i,,m) ha[i].a = read(),ha[i].b = read();
rep(i,,g) li[i].a = read(),li[i].b = read();
solve();
return ;
}

POJ2749 Building road的更多相关文章

  1. [POJ2749]Building roads(2-SAT)

    Building roads Time Limit: 2000MS   Memory Limit: 65536K Total Submissions: 8153   Accepted: 2772 De ...

  2. POJ2749 Building roads 【2-sat】

    题目 Farmer John's farm has N barns, and there are some cows that live in each barn. The cows like to ...

  3. POJ2749 Building roads

    嘟嘟嘟 最近把21天漏的给不上. 今天重温了一下2-SAT,感觉很简单.就是把所有条件都转化成如果--必然能导出--.然后就这样连边建图,这样一个强连通分量中的所有点必然都是真或者假.从而根据这个点拆 ...

  4. AHOI2018训练日程(3.10~4.12)

    (总计:共90题) 3.10~3.16:17题 3.17~3.23:6题 3.24~3.30:17题 3.31~4.6:21题 4.7~4.12:29题 ZJOI&&FJOI(6题) ...

  5. mapbox 接入高德矢量地图实战

    Mapbox 作为现如今比较流行的地图框架为我们提供了漂亮的个性化地图,在平常的使用过程中可以方便的接入高德/谷歌等矢量切片地图.由于Mapbox地图数据来源于Open Street Map等国外厂商 ...

  6. Indexing Sensor Data

    In particular embodiments, a method includes, from an indexer in a sensor network, accessing a set o ...

  7. 使用随机森林实现OSM路网城市多车道信息提取

    Multilane roads extracted from the OpenStreetMap urban road network using random forests.,DOI:10.111 ...

  8. Poj2749:Building roads

    题意 有 N 个牛栏,现在通过一条通道(s1,s2)要么连到s1,要么连到s2,把他们连起来,他们之间有一些约束关系,一些牛栏不能连在同一个点,一些牛栏必须连在同一个点,现在问有没有可能把他们都连好, ...

  9. POJ2749:Building roads——题解

    http://poj.org/problem?id=2749 (这个约翰的奶牛真多事…………………………) i表示u与s1连,i+n表示u与s2连. 老规矩,u到v表示取u必须取v. 那么对于互相打架 ...

随机推荐

  1. Python之禅 吾心笃定

    自从3月19日到现在已经学习python 19天了,博客园也注册8天了.之所以一直没有急着分享学习中的知识是因为我觉得学习一道应该从心开始,所以第一篇随笔不应该说python的知识,而应该说学习心态和 ...

  2. Java使用ZXing生成/解析二维码图片

    ZXing是一种开源的多格式1D/2D条形码图像处理库,在Java中的实现.重点是在手机上使用内置摄像头来扫描和解码设备上的条码,而不与服务器通信.然而,该项目也可以用于对桌面和服务器上的条形码进行编 ...

  3. MySQL中间件之ProxySQL_读写分离/查询重写配置

    MySQL中间件之ProxySQL_读写分离/查询重写配置 Posted on 2016-12-25 by mark blue, mark Leave a comment MySQL 1.闲扯几句 读 ...

  4. HDU 3537 Mock Turtles型翻硬币游戏

    题目大意: 每次可以翻1个或者2个或者3个硬币,但要保证最右边的那个硬币是正面的,直到不能操作为输,这题目还有说因为主人公感情混乱可能描述不清会有重复的硬币说出,所以要去重 这是一个Mock Turt ...

  5. 【NOIP2017练习】论战大原题(并查集)

    题意:给定一个n个点m条边的无向图.定义一条路径的长度为路径上最小边的权值. 定义dist(i,j)为起点为i,终点为j的长度最长的路径的长度.求出第k大的dist(i,j)(i<j). 对于所 ...

  6. 【BZOJ4583】购物(组合计数)

    题意:商店出售3种颜色的球,分别为红.绿.蓝. 城市里有n个商店,第i个商店在第First_i天开始营业,连续营业Red_i+Green_i+Blue_i天,每个商店每天只能出售一种颜色的球. 每天最 ...

  7. Java高概率面试题目—finally

    在Java面试中关于finally的面试题目出现的概率非常高,而且一旦面试官问起绝不会是蜻蜓点水,而是会向你发起层层递进地“连环问”,并且回答这系列问题常常需要代码的辅助,可谓考验基础的面试利题.究竟 ...

  8. QQ - Linux中文Wiki

    QQ:http://linux-wiki.cn/wiki/zh-hans/QQ 此页由张凯于2013年7月7日 (星期日) 14:00的最后更改. 在陈泓旭和沧之声和Linux Wiki用户Chenx ...

  9. hdu - 2660 Accepted Necklace (二维费用的背包问题)

    http://acm.hdu.edu.cn/showproblem.php?pid=2660 f[v][u]=max(f[v][u],f[v-1][u-w[i]]+v[i]; 注意中间一层必须逆序循环 ...

  10. nyoj_176_整数划分(二)_201404261715

    整数划分(二) 时间限制:1000 ms  |  内存限制:65535 KB 难度:3   描述 把一个正整数m分成n个正整数的和,有多少种分法? 例:把5分成3个正正数的和,有两种分法: 1 1 3 ...