HDU5870 Alice's Adventure in Wonderland
大概做法是这样的
考虑最朴素的做法,预处理出1到所有点的最短路数组dis1和方案数数组cnt1,和预处理出n到所有点的最短路数组dis2和方案数数组出cnt2,然后暴力枚举点对(A,B),如果A和B之间没有连边,那么就可以考虑添加一条正权边,满足这个条件就能添加dis1[A]+dis2[B]+1<=dis1[n],且cnt1[A]*cnt2[B]>=X,由于是要使方案增加,所以将边权设为dis1[n]-(dis1[A]+dis2[B])是最好的,因为可以继承原有的最短路方案数。那么由于(A,B)和(B,A)只算一次,那么第一维枚举到A第二维枚举到B,和第一维枚举到B第二维枚举到A会不会算同一种呢,可以证明这种情况并不会出现重复技计数。
那么考虑优化,枚举点A,点B需满足dis1[A]+dis2[B]+1<=dis1[n],那么可以将dis2进行排序,然后二分出临界范围,然后查询出这个范围内cnt2[B]>=X/cnt[A]的数目,离线的话做法估计挺多的,我代码里用了主席树,最后还需要去掉范围内已经连边的点和自身。时间复杂度O(nlogn)
代码
#include<cstdio>
#include<vector>
#include<set>
#include<queue>
#include<algorithm>
#define mp make_pair
#define pb push_back
#define fi first
#define sc second
using namespace std;
const int N = ;
const int M = ;
const int inf = ;
typedef pair<int,int> P;
priority_queue<P,vector<P>,greater<P> > Q;
int n,m,i,a,b,c,dis[N],cnt[N],dis1[N],cnt1[N],dis2[N],cnt2[N],X;
int id[N],ID[N],Id[N];
vector<P> e[N];
void gao(int x)
{
int i;
for (i=;i<=n;i++)
dis[i]=inf,cnt[i]=;
dis[x]=;
cnt[x]=;
Q.push(mp(,x));
while (!Q.empty())
{
P tmp=Q.top();
Q.pop();
x=tmp.sc;
if (dis[x]!=tmp.fi) continue;
for (i=;i<e[x].size();i++)
if (dis[x]+e[x][i].sc<dis[e[x][i].fi])
{
dis[e[x][i].fi]=dis[x]+e[x][i].sc;
cnt[e[x][i].fi]=cnt[x];
Q.push(mp(dis[e[x][i].fi],e[x][i].fi));
}
else
if (dis[x]+e[x][i].sc==dis[e[x][i].fi])
{
cnt[e[x][i].fi]+=cnt[x];
if (cnt[e[x][i].fi]>X) cnt[e[x][i].fi]=X;
}
}
} int ls[M],rs[M],s[M],tot,root[N];
void build(int &x,int a,int b)
{
x=++tot;
ls[x]=rs[x]=s[x]=;
if (b-a>)
{
int m=(a+b)>>;
build(ls[x],a,m);
build(rs[x],m,b);
}
}
void insert(int y,int &x,int a,int b,int l,int r)
{
x=++tot;
ls[x]=ls[y];rs[x]=rs[y];s[x]=s[y]+;
if ((a<=l)&&(r<=b))
return;
int m=(l+r)>>;
if (a<m) insert(ls[y],ls[x],a,b,l,m);
if (m<b) insert(rs[y],rs[x],a,b,m,r);
}
int query(int x,int a,int b,int l,int r)
{
if ((a<=l)&&(r<=b))
return s[x];
int m=(l+r)>>,ans=;
if (a<m) ans+=query(ls[x],a,b,l,m);
if (m<b) ans+=query(rs[x],a,b,m,r);
return ans;
}
bool cmp(int a,int b)
{
return dis2[a]<dis2[b];
}
bool CMP(int a,int b)
{
return cnt2[a]>cnt2[b];
}
int main()
{
while (~scanf("%d%d",&n,&m))
{
if (n+m==) return ;
for (i=;i<=n;i++) e[i].clear();
scanf("%d",&X);
for (i=;i<=m;i++)
{
scanf("%d%d%d",&a,&b,&c);
e[a].pb(mp(b,c));
e[b].pb(mp(a,c));
}
gao();
for (i=;i<=n;i++)
dis1[i]=dis[i],cnt1[i]=cnt[i];
gao(n);
for (i=;i<=n;i++)
dis2[i]=dis[i],cnt2[i]=cnt[i]; tot=;
build(root[],,n);
for (i=;i<=n;i++)
id[i]=i;
sort(id+,id++n,cmp);
for (i=;i<=n;i++)
ID[id[i]]=i; for (i=;i<=n;i++)
Id[i]=i;
sort(Id+,Id++n,CMP);
for (i=;i<=n;i++)
insert(root[i-],root[i],ID[Id[i]]-,ID[Id[i]],,n);
long long ans=;
for (i=;i<=n;i++)
{
int l=,r=n;
while (l<=r)
{
m=(l+r)>>;
if (dis2[id[m]]+dis1[i]+<=dis1[n]) l=m+;else r=m-;
}
int j=r; l=;r=n;
while (l<=r)
{
m=(l+r)>>;
if (1LL*cnt1[i]*cnt2[Id[m]]>=X) l=m+;else r=m-;
} if (j) ans=ans+query(root[r],,j,,n); for (int k=;k<e[i].size();k++)
if (dis2[e[i][k].fi]++dis1[i]<=dis1[n])
if (1LL*cnt1[i]*cnt2[e[i][k].fi]>=X) ans--; if (dis1[i]+dis2[i]+<=dis1[N])
if (1LL*cnt1[i]*cnt2[i]>=X) ans--; }
printf("%lld\n",ans);
}
}
HDU5870 Alice's Adventure in Wonderland的更多相关文章
- the little schemer 笔记(10)
第十章 What Is the Value of All of This? entry条目 是由list表组成的 pair 对,pair 对的第一个list表是集合 set.另外,两个list表的长 ...
- Comparing the Performance of .NET Serializers(zz)
The .NET framework comes with a variety of different serializers. Hopefully, my overview of these se ...
- zoj Treasure Hunt IV
Treasure Hunt IV Time Limit: 2 Seconds Memory Limit: 65536 KB Alice is exploring the wonderland ...
- RSA实例破解
Description: Decode the message. You intercept the following message, which you know has been encode ...
- ZOJ3629 Treasure Hunt IV(找到规律,按公式)
Treasure Hunt IV Time Limit: 2 Seconds Memory Limit: 65536 KB Alice is exploring the wonderland ...
- python抓取数据构建词云
1.词云图 词云图,也叫文字云,是对文本中出现频率较高的"关键词"予以视觉化的展现,词云图过滤掉大量的低频低质的文本信息,使得浏览者只要一眼扫过文本就可领略文本的主旨. 先看几个词 ...
- 生活英语读写MOOC-Literature Tutor-有声名著阅读推荐
生活英语读写MOOC-Literature Tutor-有声名著阅读推荐 1. Alice's Adventures in Wonderland 爱丽丝漫游奇境记 音频与文本下载地址:链接:http: ...
- September 05th 2017 Week 36th Tuesday
I always in the deepest despair, meet the most beautiful sunrise. 我总是在最深的绝望里遇见最美丽的惊喜. Some pessimist ...
- September 04th 2017 Week 36th Monday
Try not to become a man of success but rather try to become a man of value. 不要努力去做一个成功的人,而要努力去做一个有价值 ...
随机推荐
- js学习
2014-02-21 var p=function(){}(); //表示定义一个变量P,变量后面的函数为返回值 var p = function(){return 'abc';}(); alert( ...
- html和css书写规范
HTML 规范 分离的标记.样式和脚本 结构.表现.行为分离 在可能情况下验证你的标记 使用编辑器验证你的标记是否正确,一般编辑器都自带有这个功能. 技术不支持的时候使用备胎,如canvas 编码格式 ...
- 如何记录搜索引擎爬行记录php版
写博客也有一段时间了,为什么搜索引擎迟迟不收录你的页面呢?想知道每天都有哪些蜘蛛“拜访”你的网站吗?作为一名网站长,有必要知道每天都有哪些蜘蛛爬行过你的网站,以便于了解各搜索引擎蜘蛛爬行频率,对网站进 ...
- IOS ReactiveCocoa
一 前提: 在iOS开发过程中,当某些事件响应时,需处理的某些业务逻辑 Eg. 按钮点击:action ScrollView滚动:delegate 属性值改变:KVO ReactiveCocoa为事件 ...
- 那些年一起用过的iOS开发利器之CocoaPods
本系列所有工具的简介见:http://www.cnblogs.com/lloydsheng/p/3637606.html CocoaPods是一个负责管理iOS项目中第三方开源代码的工具.CocoaP ...
- win7下装完ubuntu linux后,开机画面怎直接进入linux了,win7怎么启动
修复 Windows 7 启动项重新启动ubuntu之后,结果发现选择windows 7的启动项,又进入到Ubuntu的安装界面.下面来说明如何修复,进人Ubuntu系统,打开“应用程序---附件-- ...
- JQUERY attr prop 的区别 一个已经被淘汰
在做jquery 全选 全不选的项目中, 1..prop( propertyName ) 获取匹配集合中第一个元素的Property的值 2. .prop( propertyName, value ) ...
- buy
<script type="text/javascript"> var is_enabled = -1; var checkSubmitFlg = false; var ...
- 安装运行Hadoop
1 准备环境 1.1 Ubuntu 或者 VMware Workstation Pro+Ubuntu 1.2 Jdk 1.3 eclipse 或其他开发工具(可选) 2 安装Hadoop 2.1 从h ...
- ajax原理和跨域解决方法
ajax是异步的 JavaScript 和 XML.通过在后台与服务器进行少量数据交换,AJAX 可以使网页实现异步更新.这意味着可以在不重新加载整个网页的情况下,对网页的某部分进行更新. 1--启动 ...