BestCoder Round钾E Road(hdu 5669)【線分樹+層状図が最も短絡的】
3792 ワード
リンク:http://bestcoder.hdu.edu.cn/contests/contest_chinese eproblem.php?cid=688&pid=1005
中国語の問題
公式テーマの解説はとても詳しくなりました。ここはもう転ばないです。肝心なところはもう注釈しました。
コード:
中国語の問題
公式テーマの解説はとても詳しくなりました。ここはもう転ばないです。肝心なところはもう注釈しました。
コード:
#include <algorithm>
#include <iostream>
#include <iostream>
#include <cstring>
#include <cstdio>
#include <string>
#include <vector>
#include <queue>
#include <cmath>
#include <stack>
#include <set>
#include <map>
#include <ctime>
#define INF 0x7fffffff
#define Mn 50010*10
#define Mm 2000010
#define mod 1000000007
#define CLR(a,b) memset((a),(b),sizeof((a)))
#define CPY(a,b) memcpy ((a), (b), sizeof((a)))
#pragma comment(linker, "/STACK:102400000,102400000")
#define ul (u<<1)
#define ur ((u<<1)|1)
#define cnt 4*n
using namespace std;
typedef long long ll;
struct edge {
int v,w,next;
}e[Mm];
struct node {
int v,cost;
node(){}
node(int v,int cost):v(v),cost(cost){}
bool operator <(const node a) const {
return a.cost<cost;
}
};
int tot,head[Mn];
void addedge(int u,int v,int w) {
e[tot].v=v;
e[tot].w=w;
e[tot].next=head[u];
head[u]=tot++;
}
int tr[Mn],tr2[Mn];
int n,k;
void build(int l,int r,int u) {
if(l==r) {
tr[l]=u;
tr2[l]=cnt+u;//
addedge(tr2[l],tr[l],0);//
return ;
}
int mid=(l+r)>>1;
build(l,mid,ul);
build(mid+1,r,ur);
addedge(ul,u,0);// a b
addedge(ur,u,0);// c d
addedge(cnt+u,cnt+ul,0);// c d
addedge(cnt+u,cnt+ur,0);
}
int s,t,w,tmp;//tmp
void query(int l,int r,int u) {
if(s<=l&&t>=r) {
addedge(u,tmp,0);
return ;
}
int mid=(l+r)>>1;
if(s<=mid) query(l,mid,ul);
if(t>mid) query(mid+1,r,ur);
}
void query2(int l,int r,int u) {
if(s<=l&&t>=r) {
addedge(tmp,u+cnt,w);
return ;
}
int mid=(l+r)>>1;
if(s<=mid) query2(l,mid,ul);
if(t>mid) query2(mid+1,r,ur);
}
priority_queue<node> q;
int dis[Mn][11],vis[Mn][11];
int ans;
void dijkstra(int st,int ed) {
st=tr[st];ed=tr2[ed];
while(!q.empty()) q.pop();
q.push(node(st,0));
CLR(dis,0x7f);
CLR(vis,0);
dis[st][0]=0;
while(!q.empty()) {
int v=q.top().v;
int u=(v-1)%tmp+1;//
int x=(v-u)/tmp;
q.pop();
if(vis[u][x]) continue;
vis[u][x]=1;
for(int i=head[u];~i;i=e[i].next) {
int v=e[i].v;
int cost=e[i].w;
if(!vis[v][x]&&dis[v][x]>dis[u][x]+cost) {
dis[v][x]=dis[u][x]+cost;
q.push(node(v+x*tmp,dis[v][x]));
}
if(x<k) {
if(!vis[v][x+1]&&dis[v][x+1]>dis[u][x]) {
dis[v][x+1]=dis[u][x];
q.push(node(v+(x+1)*tmp,dis[v][x+1]));
}
}
}
}
for(int i=0;i<=k;i++)
ans=min(ans,dis[ed][i]);
}
void init() {
tot=0;
CLR(head,-1);
}
int main() {
init();
int m,a,b,c,d;
scanf("%d",&n);
scanf("%d%d%d",&n,&m,&k);
build(1,n,1);
tmp=cnt*2;
for(int i=0;i<m;i++) {
scanf("%d%d%d%d%d",&a,&b,&c,&d,&w);
tmp++;s=a;t=b;
query(1,n,1);
s=c;t=d;
query2(1,n,1);
tmp++;
query(1,n,1); //
s=a;t=b;
query2(1,n,1);
}
ans=INF;
dijkstra(1,n);
if(ans>=INF) printf("CreationAugust is a sb!
");
else printf("%d
",ans);
return 0;
}