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)

  代码

  1 #include<cstdio>
  2 #include<vector>
  3 #include<set>
  4 #include<queue>
  5 #include<algorithm>
  6 #define mp make_pair
  7 #define pb push_back
  8 #define fi first
  9 #define sc second
 10 using namespace std;
 11 const int N = 201010;
 12 const int M = 2010101;
 13 const int inf = 2100000000;
 14 typedef pair<int,int> P;
 15 priority_queue<P,vector<P>,greater<P> > Q;
 16 int n,m,i,a,b,c,dis[N],cnt[N],dis1[N],cnt1[N],dis2[N],cnt2[N],X;
 17 int id[N],ID[N],Id[N];
 18 vector<P> e[N];
 19 void gao(int x)
 20 {
 21     int i;
 22     for (i=1;i<=n;i++)
 23     dis[i]=inf,cnt[i]=0;
 24     dis[x]=0;
 25     cnt[x]=1;
 26     Q.push(mp(0,x));
 27     while (!Q.empty())
 28     {
 29         P tmp=Q.top();
 30         Q.pop();
 31         x=tmp.sc;
 32         if (dis[x]!=tmp.fi) continue;
 33         for (i=0;i<e[x].size();i++)
 34         if (dis[x]+e[x][i].sc<dis[e[x][i].fi])
 35         {
 36             dis[e[x][i].fi]=dis[x]+e[x][i].sc;
 37             cnt[e[x][i].fi]=cnt[x];
 38             Q.push(mp(dis[e[x][i].fi],e[x][i].fi));
 39         }
 40         else
 41         if (dis[x]+e[x][i].sc==dis[e[x][i].fi])
 42         {
 43             cnt[e[x][i].fi]+=cnt[x];
 44             if (cnt[e[x][i].fi]>X) cnt[e[x][i].fi]=X;
 45         }
 46     }
 47 }
 48
 49 int ls[M],rs[M],s[M],tot,root[N];
 50 void build(int &x,int a,int b)
 51 {
 52     x=++tot;
 53     ls[x]=rs[x]=s[x]=0;
 54     if (b-a>1)
 55     {
 56         int m=(a+b)>>1;
 57         build(ls[x],a,m);
 58         build(rs[x],m,b);
 59     }
 60 }
 61 void insert(int y,int &x,int a,int b,int l,int r)
 62 {
 63     x=++tot;
 64     ls[x]=ls[y];rs[x]=rs[y];s[x]=s[y]+1;
 65     if ((a<=l)&&(r<=b))
 66     return;
 67     int m=(l+r)>>1;
 68     if (a<m) insert(ls[y],ls[x],a,b,l,m);
 69     if (m<b) insert(rs[y],rs[x],a,b,m,r);
 70 }
 71 int query(int x,int a,int b,int l,int r)
 72 {
 73     if ((a<=l)&&(r<=b))
 74     return s[x];
 75     int m=(l+r)>>1,ans=0;
 76     if (a<m) ans+=query(ls[x],a,b,l,m);
 77     if (m<b) ans+=query(rs[x],a,b,m,r);
 78     return ans;
 79 }
 80 bool cmp(int a,int b)
 81 {
 82     return dis2[a]<dis2[b];
 83 }
 84 bool CMP(int a,int b)
 85 {
 86     return cnt2[a]>cnt2[b];
 87 }
 88 int main()
 89 {
 90     while (~scanf("%d%d",&n,&m))
 91     {
 92     if (n+m==0) return 0;
 93     for (i=1;i<=n;i++) e[i].clear();
 94     scanf("%d",&X);
 95     for (i=1;i<=m;i++)
 96     {
 97         scanf("%d%d%d",&a,&b,&c);
 98         e[a].pb(mp(b,c));
 99         e[b].pb(mp(a,c));
100     }
101     gao(1);
102     for (i=1;i<=n;i++)
103     dis1[i]=dis[i],cnt1[i]=cnt[i];
104     gao(n);
105     for (i=1;i<=n;i++)
106     dis2[i]=dis[i],cnt2[i]=cnt[i];
107
108     tot=0;
109     build(root[0],0,n);
110     for (i=1;i<=n;i++)
111     id[i]=i;
112     sort(id+1,id+1+n,cmp);
113     for (i=1;i<=n;i++)
114     ID[id[i]]=i;
115
116     for (i=1;i<=n;i++)
117     Id[i]=i;
118     sort(Id+1,Id+1+n,CMP);
119     for (i=1;i<=n;i++)
120         insert(root[i-1],root[i],ID[Id[i]]-1,ID[Id[i]],0,n);
121     long long ans=0;
122     for (i=1;i<=n;i++)
123     {
124         int l=1,r=n;
125         while (l<=r)
126         {
127             m=(l+r)>>1;
128             if (dis2[id[m]]+dis1[i]+1<=dis1[n]) l=m+1;else r=m-1;
129         }
130         int j=r;
131
132         l=1;r=n;
133         while (l<=r)
134         {
135             m=(l+r)>>1;
136             if (1LL*cnt1[i]*cnt2[Id[m]]>=X) l=m+1;else r=m-1;
137         }
138
139         if (j) ans=ans+query(root[r],0,j,0,n);
140
141
142         for (int k=0;k<e[i].size();k++)
143         if (dis2[e[i][k].fi]+1+dis1[i]<=dis1[n])
144         if (1LL*cnt1[i]*cnt2[e[i][k].fi]>=X) ans--;
145
146         if (dis1[i]+dis2[i]+1<=dis1[N])
147         if (1LL*cnt1[i]*cnt2[i]>=X) ans--;
148
149     }
150     printf("%lld\n",ans);
151     }
152 }

HDU5870 Alice's Adventure in Wonderland

时间: 2024-11-05 16:35:05

HDU5870 Alice's Adventure in Wonderland的相关文章

柴郡猫技术--C++中的PIMPL设计模式

另一个 Blog 地址:http://insaneguy.me 原文链接:http://insaneguy.me/2015/04/05/cheshire_cat_in_cpp-pimpl_idiom/ C++ 中的"柴郡猫技术"(Cheshire Cat Idiom),又称为 PIMPL(Pointer to IMPLementation) ,Opaque Pointer 等,是一种在类中只定义接口,而将私有数据成员封装在另一个实现类中的惯用法.该方法主要是为了隐藏类的数据以及减轻编译

ZOJ 3629(找规律)

Treasure Hunt IV Time Limit: 2 Seconds      Memory Limit: 65536 KB Alice is exploring the wonderland, suddenly she fell into a hole, when she woke up, she found there are b - a + 1 treasures labled afrom b in front of her. Alice was very excited but

zoj Treasure Hunt IV

Treasure Hunt IV Time Limit: 2 Seconds      Memory Limit: 65536 KB Alice is exploring the wonderland, suddenly she fell into a hole, when she woke up, she found there are b - a + 1 treasures labled a from b in front of her.Alice was very excited but

ZOJ3629 Treasure Hunt IV(找规律,推公式)

Treasure Hunt IV Time Limit: 2 Seconds      Memory Limit: 65536 KB Alice is exploring the wonderland, suddenly she fell into a hole, when she woke up, she found there are b - a + 1 treasures labled a from b in front of her. Alice was very excited but

iTextRenderer(Flying Saucer) HTML转PDF

iTextRenderer 在依赖 iText 的基础上,单独实现了HTML渲染PDF,基本上能实现 CSS 2.1的整体性,并且完全符合 W3C 规范. 使用html和css定义样式和呈现的内容.如下流程图: 中文支持 首先需要添加中文字库,也就是你的页面中用到的所有字体: ITextFontResolver fontResolver = renderer.getFontResolver(); fontResolver.addFont("C:/Windows/Fonts/simsun.ttc&

zoj 3629 Treasure Hunt IV(找规律)

Alice is exploring the wonderland, suddenly she fell into a hole, when she woke up, she found there are b - a + 1 treasures labled a fromb in front of her.Alice was very excited but unfortunately not all of the treasures are real, some are fake.Now w

zoj 3629 Treasure Hunt IV 打表找规律

H - Treasure Hunt IV Time Limit:2000MS     Memory Limit:65536KB     64bit IO Format:%lld & %llu Description Alice is exploring the wonderland, suddenly she fell into a hole, when she woke up, she found there are b - a + 1 treasures labled a from b in

September 04th 2017 Week 36th Monday

Try not to become a man of success but rather try to become a man of value. 不要努力去做一个成功的人,而要努力去做一个有价值的人. A man of success is also a man of vlaue. I want to be a man of success, in that process, my work will contribute a lot to the whole human being. E

codeforces_346A Alice and Bob(数学)

题目链接:http://codeforces.com/problemset/problem/346/A 参考链接:http://blog.csdn.net/loy_184548/article/details/50174615 感受到数学在博弈论中的强大. 考虑最后终止状态的序列-无法取出任意两个数他们的差值不存在这个序列中:那么这必定是个首项等于公差的等差序列 而这个序列是 d 2d 3d....,因此可以通过a[1] a[2] a[3] ...的最大公约数得到 然后计算有几个数没在数组中,判