【NOIP2016提高A组集训第15场11.14】过河
2016-11-14 21:50
281 查看
Description
Solution
一开始看到这道题的时候,就想,这不就是连边题吗!!!然后,一通乱连,然后放弃治疗……
(i,j)表示第i个桩放第j个圆盘。
结果连边其实非常的简单:从0向(i,j)(如果能连的话)连权为c[j]的边,然后(i,j)向终点连权为0的边(如果能连的话)。
然后(i,j)向(p,q)连边(如果能连的话)
然后跑一次spfa就能拿60分了。
我们来优化一下连边。
我们可以发现如果(i,j)可以(p,q)连边的话,那么(i,j)也可以向(p,q+1…m)连边。
那么我们考虑一个(i,j)只想一个(p,k)连边且k是最小的那么p。所以(i,j)就需要向(i,j+1)连边。
找最小的p连边,按所有点到x的路径长度排序一下,随便搞搞就好了。O(n*n*m)
然后,就可以过了。
想跑的更快吗?
打dij或spfa优化。spfa优化总结
Code
#include<iostream> #include<cstdio> #include<cstring> #include<algorithm> #include<cmath> #define fo(i,a,b) for(i=a;i<=b;i++) #define fod(i,a,b) for(i=a;i>=b;i--) #define rep(i,a) for(i=first[a];i;i=next[i]) const int maxn=257,mxx=257*257*257; using namespace std; typedef long long ll; ll i,j,k,l,t,n,m,ans,cas,w,T,mm,o; int first[maxn*maxn],last[maxn*maxn*150],next[maxn*maxn*150],num; int data[mxx]; ll d[maxn*maxn],da,chang[maxn*maxn*150],r[maxn],c[maxn]; bool bz[maxn*maxn],az; ll z,len; struct node{ll r,c;}b[maxn]; struct nod{ll a,b;}a[maxn]; struct guhou{int a;double b;}e[maxn]; bool cmp(node x,node y){return x.r<y.r||x.r==y.r&&x.c<y.c;} bool cmp1(guhou x,guhou y){return x.b<y.b;} void add(int x,int y,ll z){ last[++num]=y,next[num]=first[x],first[x]=num,chang[num]=z; } double ju(ll x,ll y,ll xx,ll yy){ double z=sqrt((xx-x)*(xx-x)+(yy-y)*(yy-y)); return z; } int hao(int x,int y){return n+(x-1)*m+y;} void spfa(){ int i,j,k,head=0,tail=1,now; double y;len=1;z=0; memset(d,127,sizeof(d));da=d[0];d[0]=0;ans=da; bz[0]=1; data[1]=0; while(head<tail){ now=data[++head]; if(len*d[now]>z){ data[++tail]=now; continue; } z-=d[now];len--; if(d[now]>=ans){bz[now]=0;continue;} if(now==T&&ans>d[now]){ ans=d[now]; } rep(i,now){ if(d[now]+chang[i]<=d[last[i]]){ d[last[i]]=d[now]+chang[i]; if(!bz[last[i]]){ bz[last[i]]=1;len++; data[++tail]=last[i];z+=d[last[i]]; if(d[last[i]]<d[data[head+1]])swap(data[tail],data[head+1]); } } } bz[now]=0; } } int main(){ // freopen("river.in","r",stdin); // freopen("river.out","w",stdout); // freopen("fan.in","r",stdin); for(scanf("%lld",&cas);cas;cas--){ scanf("%lld%lld%lld",&n,&mm,&w); fo(i,1,n)scanf("%lld%lld",&a[i].a,&a[i].b); fo(i,1,mm)scanf("%lld%lld",&b[i].r,&b[i].c); memset(first,0,sizeof(first));num=m=0; sort(b+1,b+1+mm,cmp);b[mm+1].c=0x7fffffff; fo(i,1,mm){ az=1; fo(j,i+1,mm){ if(b[i].c>b[j].c){ az=0; break; } } if(az)r[++m]=b[i].r,c[m]=b[i].c; } T=hao(n+1,1); fo(i,1,n){ fo(j,1,m){ if(r[j]>=a[i].b){ add(0,hao(i,j),c[j]); } if(r[j]+a[i].b>=w){ add(hao(i,j),T,0); } } } fo(i,1,n){ fo(j,1,m-1){ add(hao(i,j),hao(i,j+1),c[j+1]-c[j]); } } fo(i,1,n){ fo(k,1,n)e[k].a=k,e[k].b=ju(a[i].a,a[i].b,a[k].a,a[k].b); sort(e+1,e+1+n,cmp1); fo(j,1,m){ o=1; fo(k,1,n){ if(e[k].a==i)continue; while(o<=m&&(r[j]+r[o])*1.0<e[k].b)o++; if(o==m+1)break; add(hao(i,j),hao(e[k].a,o),c[o]); } } } spfa(); if(d[T]==da)printf("impossible\n"); else printf("%lld\n",d[T]); } return 0; }
相关文章推荐
- JZOJ4893【NOIP2016提高A组集训第15场11.14】过河
- 【JZOJ4893】【NOIP2016提高A组集训第15场11.14】过河
- NOIP2016提高A组集训第15场11.14 总结
- 【NOIP2016提高A组集训第12场11.10】灵知的太阳信仰
- 【NOIP2016提高A组集训第1场10.29】完美标号
- 【JZOJ4854】【NOIP2016提高A组集训第6场11.3】小澳的坐标系
- 【NOIP2016提高A组集训第2场10.30】钻石游戏
- 【NOIP2016提高A组集训第10场11.8】力场护盾
- 【JZOJ4878】【NOIP2016提高A组集训第10场11.8】时空传送
- 最近公共祖先 【NOIP2016提高A组集训第14场11.12】
- 【JZOJ4894】【NOIP2016提高A组集训第16场11.15】SJR的直线
- NOIP2016提高A组集训第16场11.15 总结
- 【JZOJ4901】【NOIP2016提高A组集训第18场11.17】矩阵
- JZOJ 4822. 【NOIP2016提高A组集训第1场10.29】完美标号
- 【JZOJ4855】【NOIP2016提高A组集训第6场11.3】荷花池塘
- JZOJ4859. 【NOIP2016提高A组集训第7场11.4】连锁店
- JZOJ4877. 【NOIP2016提高A组集训第10场11.8】力场护盾
- 【NOIP2016提高A组集训第16场11.15】兔子
- 【JZOJ4895】【NOIP2016提高A组集训第16场11.15】三部曲
- 【JZOJ4899】【NOIP2016提高A组集训第17场11.16】雪之国度