poj 2749 看的题解...
来源:互联网 发布:人口学特征 知乎 编辑:程序博客网 时间:2024/06/06 11:45
#include<iostream>#include<vector>#include<cmath>#include<cstdlib>#define N 1003#include<cstring>#include<cstdio>using namespace std;int n_barn, n_hate, n_friend; int len;int stack[2*N]; int low[2*N]; int dfn[2*N]; bool in_stack[2*N]; int scc[2*N];int color,index,top;int done;int n;struct Point{ int x,y;};Point cor1,cor2;int dist[2*N];vector <int> gt[2*N];vector<int> g[2*N];void init(int max_dist);void tarjan(int s); int get_dist(Point &p,Point &q); void solve(); int b_search(); int check();int main(){ freopen("in.txt","r",stdin); int x,y; Point point; while(cin>>n_barn>>n_hate>>n_friend){ cin>>cor1.x>>cor1.y>>cor2.x>>cor2.y; len=get_dist(cor1,cor2); n=2*n_barn; for(int i=0;i<2*N;i++) gt[i].clear(); for(int i=0;i<n_barn;i++) { scanf("%d%d",&point.x,&point.y); dist[2*i]=get_dist(point,cor1); dist[2*i+1]=get_dist(point,cor2); } for(int i=0;i<n_hate;i++) { scanf("%d%d",&x,&y); x-=1; y-=1; gt[2*x].push_back(2*y+1); gt[2*x+1].push_back(2*y); gt[2*y].push_back(2*x+1); gt[2*y+1].push_back(2*x); } for(int i=0;i<n_friend;i++) { scanf("%d%d",&x,&y); x-=1; y-=1; gt[2*x].push_back(2*y); gt[2*y].push_back(2*x); gt[2*x+1].push_back(2*y+1); gt[2*y+1].push_back(2*x+1); } x=b_search(); if(done) cout<<x<<endl; else cout<<-1<<endl; }}void init(int max_dist){ for(int i=0;i<n;i++) g[i]=gt[i]; for(int i=0;i<n_barn;i++) for(int j=i+1;j<n_barn;j++) { if(dist[2*i]+dist[2*j]>max_dist) { g[2*i].push_back(2*j+1); g[2*j].push_back(2*i+1); } if(dist[2*i]+dist[2*j+1]+len>max_dist) { g[2*i].push_back(2*j); g[2*j+1].push_back(2*i+1); } if(dist[2*i+1]+dist[2*j]+len>max_dist) { g[2*i+1].push_back(2*j+1); g[2*j].push_back(2*i); } if(dist[2*i+1]+dist[2*j+1]>max_dist) { g[2*i+1].push_back(2*j); g[2*j+1].push_back(2*i); } }}void tarjan(int s){ low[s]=dfn[s]=++index; stack[top++]=s; in_stack[s]=true; vector <int> :: iterator p; for(p=g[s].begin();p!=g[s].end();p++) { if(!dfn[*p]) {tarjan(*p); low[s]=min(low[s],low[*p]); } else if(in_stack[*p]) // 必须是在栈内 { low[s]=min(low[s],dfn[*p]); } } if(dfn[s]==low[s]) { color++; int t; do{ t=stack[top-1]; scc[t]=color; top--; in_stack[t]=false; }while(t!=s); } } void solve() { memset(in_stack,0,sizeof(in_stack)); memset(dfn,0,sizeof(dfn)); memset(low,0,sizeof(low)); index=0; top=0; color=0; for(int i=0;i<2*n;i++) if(!dfn[i]) tarjan(i); } int check() { for(int i=0;i<2*n;i+=2) { if(scc[i]==scc[i+1]) return 0; } return 1; } int get_dist(Point &p,Point &q) { return abs(p.x-q.x)+abs(p.y-q.y); }int b_search(){ done=0; int l=0;int r=5000000; int mid; while(l<r) { mid=(l+r)/2; init(mid); solve(); if(!check()) l=mid+1; else {r=mid; done=1;} } return l;}
开始题意理解错了 以为求路径总和最短,
题目描述: 有n个牛棚,两个中转点M1,M2,牛棚只能连到中转点,
而且有些牛棚只能连到相同的中转点,有些牛棚只能连在 不同的中转点;
要求最后使得牛棚之间最长距离 最小。
关于最大最小之类的,都是二分答案 多学习···
对于x y讨厌的关系:加边x->~y, y->~x, ~x -> y, ~y->x
对于x y喜欢的关系:加边x ->y, y->x ~x->~y, ~y->~x
另外,对于二分的最长路 mid: 如果直接相连的两点 d[i]+d[j] > mid,
表示必须连到不同中转点,加边i->~j, j->~i
如果两点连到不同中转点d[i]+d[j]+D>mid, 表示必须连到相同点,加边i->j, j->i
- poj 2749 看的题解...
- 楼教主男人八题 POJ 1741(树分治(我自然是看题解搞懂的))
- STL的应用 POJ 1840 Eqs 题解
- poj 2502 题解 & dijkstra的堆优化
- POJ 2975 Nim题解---简单的博弈论
- CCCC练习题的题解-给新人看的
- POJ 1011 题解
- poj-1050 题解
- poj-1088题解
- poj-1159题解
- POJ 1009题解
- POJ 1458题解
- Poj 2352 Stars 题解
- POJ 2739题解---小菜
- POJ 1753题解
- POJ 1328题解
- POJ 2049题解
- poj 2679题解
- 在 AIX 上实现 Java: 下载、安装和配置
- (连载)一步一步教你做黑白棋游戏(一)
- sql创建临时表或视图增加 自增列
- AIX 上的 Java 故障诊断:AIX 核心转储
- 2500个常用汉字(用来练普通话的)
- poj 2749 看的题解...
- 总结自己应用广度优先搜索(BFS)中的错误(记POJ 1376 Robot结题过程)
- repeater实现删除按钮
- DSP DM355 如何加载运行bin文件
- linux joystick 游戏手柄编程 (获取输入数据)
- 探索 AIX 6:新特性概述(上)
- linux powerpc i2c驱动 之 i2c设备层的注册过程
- STM32学习笔记
- Ubuntu + Windows TFTP服务器配置