cf 366D D. Dima and Trap Graph (计算所有线段共同覆盖的某段区间)
http://codeforces.com/problemset/problem/366/D
题意:给出n个点,m条边,a,b,ll,rr分别代表点a,点b相连,点a和点b的区间范围(ll,rr),然后让你选择边相连接使得可以从点1到点n,并且所有被选择的边所共同覆盖的区间范围最大。
4 4
1 2 1 10
2 4 3 5
1 3 1 5
2 4 2 7
6
4个点,4条边,现在可以从1--2--4,存在两条路径,(1,10)--(3,5)或者(1,10)——(2,7),要选择这所共同覆盖的区间范围最大的路径,那么就是(1,10)——(2,7),所覆盖的区间范围为7-2+1
若是最大区间范围没有,输出-1;
思路:仔细思考过后,会发现,其实若存在最大共同覆盖区间(p),那么区间p的左极限必然是某个区间的左端点,区间p的右极限必然是某个区间的右端点,当然这“某个区间”,可能会是一个区间,也可能会是两个区间......
如此的话,我是对所有区间按ll排序,然后枚举rr区间,找ll,用并查集判断是否可以从点1到点n.....可是wa多次......至今没有弄明白,是哪个地方思路问题?
wa代码:
#include<iostream>
#include<cstdio>
#include<cstring>
#include<vector>
#include<algorithm>
using namespace std; struct node
{
int v1,v2;
int x,y;
//int len;
} s[3*1005];
int father[3000];
int n,m;
int vist[1005],flg1,flg2,ans,xx,yy;
int cmp(const node a,const node b)
{
if(a.x<b.x)
return 1;
else
return 0;
}
int find(int x)
{
int root,i=x;
while(x!=father[x])
x=father[x];
root=x;
x=i;
while(x!=father[x])
{
i=father[x];
father[x]=root;
x=i;
}
return root;
} int main()
{
while(scanf("%d%d",&n,&m)>0)
{
for(int i=0; i<m; i++)
{
scanf("%d%d%d%d",&s[i].v1,&s[i].v2,&s[i].x,&s[i].y);
//s[i].len=s[i].y-s[i].x+1;
}
sort(s,s+m,cmp);
ans=0;
for(int i=0; i<m; i++)
{
for(int j=0; j<=n; j++)
father[j]=j;
for(int j=0;j<m;j++)
{
if(s[i].y<s[j].x)
break;
if(s[j].x>s[i].x)
continue;
if(s[i].x>s[j].y)
continue;
int s1=find(s[j].v1);
int s2=find(s[j].v2);
if(s1!=s2)
{
father[s1]=s2;
}
if(find(1)==find(n))
{
if(ans<s[j].y-s[i].x+1)
ans=s[j].y-s[i].x+1;
//printf("%d %d\n",s[i].x,s[i].y);
}
}
}
if(ans==0)
printf("Nice work, Dima!\n");
else
printf("%d\n",ans);
}
return 0;
}
然后,我依旧是对ll排序,但是这次是枚举rr来找ll,依旧是并查集判断是否联通1到n,额,ac了......有点不可思议,思考ing
ac代码:
#include<iostream>
#include<cstdio>
#include<cstring>
#include<vector>
#include<algorithm>
using namespace std; struct node
{
int v1,v2;
int x,y;
//int len;
} s[3*1005];
int father[3000];
int n,m;
int vist[1005],flg1,flg2,ans,xx,yy;
int cmp(const node a,const node b)
{
if(a.x<b.x)
return 1;
else
return 0;
}
int find(int x)
{
int root,i=x;
while(x!=father[x])
x=father[x];
root=x;
x=i;
while(x!=father[x])
{
i=father[x];
father[x]=root;
x=i;
}
return root;
} int main()
{
while(scanf("%d%d",&n,&m)>0)
{
for(int i=0; i<m; i++)
{
scanf("%d%d%d%d",&s[i].v1,&s[i].v2,&s[i].x,&s[i].y);
//s[i].len=s[i].y-s[i].x+1;
}
sort(s,s+m,cmp);
ans=0;
for(int i=0; i<m; i++)
{
for(int j=0; j<=n; j++)
father[j]=j; for(int j=0;j<m;j++)
{
if(s[i].y<s[j].x)
break;
if(s[i].y>s[j].y)
continue;
//if(s[j].x>s[i].x)
//continue;
int s1=find(s[j].v1);
int s2=find(s[j].v2);
if(s1!=s2)
{
father[s1]=s2;
}
//printf("%d %d\n",s[j].v1,s[j].v2);
if(find(1)==find(n))
{ if(ans<s[i].y-s[j].x+1)
ans=s[i].y-s[j].x+1;
break;
}
}
}
if(ans==0)
printf("Nice work, Dima!\n");
else
printf("%d\n",ans);
}
return 0;
}
经过思考,我觉得wa代码是因为rr无序,也就是说,我只对ll排序了,枚举ll所找到的rr是无规律的,导致本来有些区间是应该会先连通点1到点n的,而因为rr无序,扰乱了.....所以wa,额,为了验证是不是这样的,便有了接下来的代码:
#include<iostream>
#include<cstdio>
#include<cstring>
#include<vector>
#include<algorithm>
using namespace std; struct node
{
int v1,v2;
int x,y;
//int len;
} s[3*1005];
int father[3000];
int n,m;
int vist[1005],flg1,flg2,ans,xx,yy;
int cmp(const node a,const node b)
{
if(a.y>b.y)
return 1;
else
return 0;
}
int find(int x)
{
int root,i=x;
while(x!=father[x])
x=father[x];
root=x;
x=i;
while(x!=father[x])
{
i=father[x];
father[x]=root;
x=i;
}
return root;
} int main()
{
while(scanf("%d%d",&n,&m)>0)
{
for(int i=0; i<m; i++)
{
scanf("%d%d%d%d",&s[i].v1,&s[i].v2,&s[i].x,&s[i].y);
//s[i].len=s[i].y-s[i].x+1;
}
sort(s,s+m,cmp);
ans=0;
for(int i=0; i<m; i++)
{
for(int j=0; j<=n; j++)
father[j]=j; for(int j=0;j<m;j++)
{
if(s[i].x>s[j].y)
continue;
if(s[i].y<s[j].x)
continue;
//if(s[i].x)
if(s[j].x>s[i].x)
continue;
int s1=find(s[j].v1);
int s2=find(s[j].v2);
if(s1!=s2)
{
father[s1]=s2;
}
//printf("%d %d\n",s[j].v1,s[j].v2);
if(find(1)==find(n))
{ if(ans<s[j].y-s[i].x+1)
ans=s[j].y-s[i].x+1;
break;
}
}
}
if(ans==0)
printf("Nice work, Dima!\n");
else
printf("%d\n",ans);
}
return 0;
}
ac了......真是这样的哈......
具体的来说,我觉得解一道题目,不仅仅只是ac了就可以的........
这道题目,对于区间的排序问题,有讲究的。比如说只有四个点的情况,1 2 1 10与2 4 2 7;
表示点1和点2相连,区间值为1--10,点2与点4相连,区间值为2--7;
现在按区间的ll从小到大排序:
s[0].v1=1 s[0].v2=2 s[0].ll=1 s[0].rr=10;
s[1].v1=2 s[1].v2=4 s[1].ll=2 s[1].rr=7;
若枚举ll来确定rr,那么就会出现10-2+1的输出,其实为什么会这样?自己在纸上动手画画就可以明白;
但枚举rr来确定ll,却不会产生这样的情况......
同理,若是按照区间rr从大到小排序,然后枚举ll来确定rr,也会是正确的.......至于为什么一种要从小到大,而另一种要从大到小,找两个这样的区间,一个区间被另一个区间包含,然后动手画画,就可以明白........
cf 366D D. Dima and Trap Graph (计算所有线段共同覆盖的某段区间)的更多相关文章
- Codeforces 336D Dima and Trap Graph 并查集
Dima and Trap Graph 枚举区间的左端点, 然后那些左端点比枚举的左端点小的都按右端点排序然后并查集去check #include<bits/stdc++.h> #defi ...
- Codefroces 366 D Dima and Trap Graph (最短路)
Dima and Trap Graph 题意:Dima和Inna越来越喜欢对方,但是Dima的室友缺很没有热情出去玩,然后Dima就把他室友Seryozha骗进了陷阱里.现在Seryozha想要从陷阱 ...
- cf D. Dima and Trap Graph
http://codeforces.com/contest/366/problem/D 遍历下界,然后用二分求上界,然后用dfs去判断是否可以. #include <cstdio> #in ...
- 【BZOJ5334】数学计算(线段树)
[BZOJ5334]数学计算(线段树) 题面 BZOJ 洛谷 题解 简单的线段树模板题??? 咕咕咕. #include<iostream> #include<cstdio> ...
- CF#214 C. Dima and Salad 01背包变形
C. Dima and Salad 题意 有n种水果,第i个水果有一个美味度ai和能量值bi,现在要选择部分水果做沙拉,假如此时选择了m个水果,要保证\(\frac{\sum_{i=1}^ma_i}{ ...
- cf B. Little Dima and Equation
http://codeforces.com/contest/460/problem/B import java.util.*; import java.math.*; public class Mai ...
- cf 366C C. Dima and Salad(01背包)
http://codeforces.com/contest/366/problem/C 题意:给出n个水果的两种属性a属性和b属性,然后挑选苹果,选择的苹果必须要满足这样一个条件:,现在给出n,k,要 ...
- POJ 2125 Destroying the Graph 二分图最小点权覆盖
Destroying The Graph Time Limit: 2000MS Memory Limit: 65536K Total Submissions: 8198 Accepted: 2 ...
- CF 316E3 Summer Homework(斐波那契矩阵+线段树)
题目链接:http://codeforces.com/problemset/problem/316/E3 题意:一个数列A三种操作:(1)1 x y将x位置的数字修改为y:(2)2 x y求[x,y] ...
随机推荐
- 【Spring】SpringMVC之REST编程风格
REST架构是一个抽象的概念,目前主要是基于HTTP协议实现,其目的是为了提高系统的可伸缩性.降低应用之间的耦合度.便于架构分布式处理程序.当使用多种语言进行开发的时候,每一种语言对URL的处理不同, ...
- hibernate 注释 唯一键约束 uniqueConstraints
@Table 注解包含一个schema和一个catelog 属性,使用@UniqueConstraints 可以定义表的唯一约束. 如果是联合约束就用下面这种 @Table(name="tb ...
- ASP.NET实现二维码 ASP.Net上传文件 SQL基础语法 C# 动态创建数据库三(MySQL) Net Core 实现谷歌翻译ApI 免费版 C#发布和调试WebService ajax调用WebService实现数据库操作 C# 实体类转json数据过滤掉字段为null的字段
ASP.NET实现二维码 using System;using System.Collections.Generic;using System.Drawing;using System.Linq;us ...
- AndroidStudio编译错误:Error: null value in entry: blameLogFolder=null
今天写项目的时候,电脑开了个WiFi热点,然后这个热点和window驱动不兼容,有时候会导致电脑重启,重启之后AndroidStudio编译就报错了, Error: null value in ent ...
- 64位FreeSWITCH编译安装(版本1.4.20)
1.安装64位的CentOS6.5操作系统(勾选的服务器版本安装). 2.下载FreeSWITCH安装包以及关联的lib库.下载地址http://files.freeswitch.org/downlo ...
- 近期对招聘Android开发者的一些思考
公司要招聘Android开发者,故面试了大概十来个人.由于是小公司,所以来的人大多是90后,比較年轻.90后大概二十三四岁吧,从简历上看都写了一到两年的工作经验. 也由于是小公司,所以对工作经验这些没 ...
- CentOS 7 host-only 设置上网
CentOS 7 ifcfg-enp0s3: HWADDR=::::F6: TYPE=Ethernet BOOTPROTO=static #dhcp DEFROUTE=yes PEERDNS=yes ...
- jmeter响应信息unicode 编码转成中文
在jmeter 发送请求过程中,有时候后台返回的是unicode 代码,如: {"status":-1,"msg":"\u63d0\u4ea4\u65 ...
- django -- 用包来组织数据库模型
默认情况下一个django app的所有模型都保存在一个叫models.py的文件中.这样事实是不方便管理的: 通过包来组织模型是比较方便的. 一.第一步:删除models.py: rm -rf mo ...
- oozie 常用命令
1.验证wokflow.xmloozie validate /appcom/apps/hduser0401/mbl_webtrends/workflow.xml 2.提交作业,作业进入PREP状态 o ...