注册 登录  
 加关注
   显示下一条  |  关闭
温馨提示!由于新浪微博认证机制调整,您的新浪微博帐号绑定已过期,请重新绑定!立即重新绑定新浪微博》  |  关闭

时光机TimeMachine

——一个退役OIer

 
 
 

日志

 
 

[BZOJ1880][Sdoi2009]Elaxia的路线  

2014-07-18 20:10:52|  分类: Problems |  标签: |举报 |字号 订阅

  下载LOFTER 我的照片书  |
图论题。
Noip夏令营讲的题目
据说用DP但是没听懂……

然后用了一种很巧妙的方法

#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<cmath>
#include<queue>
using namespace std;
const int N = 1500+10;
const int MAX = 1000000000;
queue<int>dui;
struct list{
list(){next=NULL;}
int d,len;
list *next;
void push(int a,int b){
list *l=new list;
l->next=next;next=l;
l->d=a;
l->len=b;
}
}point[N];
int scan(){
char cc=' ';int re=0,fh=1;
while(cc==' '||cc=='\r'||cc=='\n'){cc=getchar();}
if(cc=='+'){cc=getchar();fh=1;}
if(cc=='-'){cc=getchar();fh=-1;}
while('0'<=cc&&cc<='9'){
re=re*10+cc-'0';
cc=getchar();
}
return re*fh;
}
int n,m;
int s1[N],t1[N],s2[N],t2[N];
short v[N];
void spfa(int start,int dis[]){
for(int i=1;i<=n;i++) dis[i]=MAX;
memset(v,0,sizeof(v));
dis[start]=0;
v[start]=1;
dui.push(start);
while(!dui.empty()){
int now=dui.front();dui.pop();
for(list *i = point[now].next;i!=NULL;i=i->next)
if(dis[now] + i->len < dis[i->d]){
dis[i->d] = dis[now] + i->len;
if(!v[i->d]){
v[i->d]=1;
dui.push(i->d);
}
}
v[now]=0;
}
}
int min(int a,int b){if(a<b) return a;return b;}
int main(){
int i,j;
int a,b,c;
freopen("input.txt","r",stdin);
n=scan();m=scan();
s1[0]=scan();t1[0]=scan();s2[0]=scan();t2[0]=scan();
for(i=1;i<=m;i++){
a=scan();b=scan();c=scan();
point[a].push(b,c);
point[b].push(a,c);
}
spfa(s1[0],s1);
spfa(t1[0],t1);
spfa(s2[0],s2);
spfa(t2[0],t2);
int ans=0,dis1=s1[t1[0]],dis2=s2[t2[0]];
for(i=1;i<=n;i++)
for(j=i+1;j<=n;j++)
if(s1[i]+t1[i]==dis1&&s2[i]+t2[i]==dis2&&s1[j]+t1[j]==dis1&&s2[j]+t2[j]==dis2){
int lin;
lin = dis1+dis2;
a=i;b=j;
//保证正序
if(s1[a]>s1[b])swap(a,b);
lin-=s1[a]+t1[b];
if(s2[a]>s2[b])swap(a,b);
lin-=s2[a]+t2[b];

lin/=2;
if(lin>ans)ans=lin;
}
printf("%d\n",ans);
return 0;
}

四遍SPFA

然后因为公共路径一定是连续的

所以枚举这两个端点

两个端点的最短路径如果用Floyd的话必然T

但是可以发现用做差可以直接得到

设dis(S1->T1) = dis1     dis(S2->T2) = dis2

设如下四条红路长度和为L[BZOJ1880][Sdoi2009]Elaxia的路线 - 时光机 - 时光机TimeMachine

dis(i,j) = (dis1+dis2-L)/2

要考虑S1->T1 S2->T2的方向是否相同


错误统计两点间距离做法:

for(i=1~n)

for(j=1~n)

if(i!=j)

lin = dis1+dis2-min(s1[i],t1[i])-min(s2[i],t2[i])-min(s1[j],t1[j])-min(s2[j],t2[j]);

导致我WA半天-A-

反例就不举了


另-----

Wangxz神犇用SPFA后O(1)得到答案

然后直接虐到Rank2

其实是错误的

所以就不介绍了

其实我这个方法是因为理解错了Wangxz神犇的意思而获得的。。。

  评论这张
 
阅读(26)| 评论(0)
推荐 转载

历史上的今天

在LOFTER的更多文章

评论

<#--最新日志,群博日志--> <#--推荐日志--> <#--引用记录--> <#--博主推荐--> <#--随机阅读--> <#--首页推荐--> <#--历史上的今天--> <#--被推荐日志--> <#--上一篇,下一篇--> <#-- 热度 --> <#-- 网易新闻广告 --> <#--右边模块结构--> <#--评论模块结构--> <#--引用模块结构--> <#--博主发起的投票-->
 
 
 
 
 
 
 
 
 
 
 
 
 
 

页脚

网易公司版权所有 ©1997-2017