Travel
题号:NC14292
时间限制:C/C++ 1秒,其他语言2秒
空间限制:C/C++ 32768K,其他语言65536K
64bit IO Format: %lld
题目描述
精灵王国有N座美丽的城市,它们以一个环形排列在Bzeroth的大陆上。其中第i座城市到第i+1座城市花费的时间为d[i]。特别地,第N座城市到第1座城市花费的时间为d[N]。这些道路都是双向的。
另外,精灵们在数千年的时间里建造了M座传送门,第i座传送门连接了城市u[i]与城市v[i],并且需要花费w[i]的时间通过(可能有两座传送门连接了同一对城市,也有可能一座传送门连接了相同的两座城市)。这些传送门都是双向的。
小S是精灵王国交通部部长,她的职责是为精灵女王设计每年的巡查路线。每次陛下会从某一个城市到达另一个城市,沿路调查每个城市的治理情况,她需要找出一条用时最短的路线。
输入描述:
第一行为2个整数N、M。 第二行为N个正整数d[i]。 接下来M行每行三个正整数u[i]、v[i]、w[i]。 第M+3行为一个正整数Q,表示需要设计路线的次数。 接下来Q行每行两个正整数x、y,表示一次从城市x到城市y的旅行。
输出描述:
Q行每行一个正整数表示该次旅行的最短时间。
示例1
输入
4 1 1 2 3 6 1 3 2 5 1 2 1 4 1 3 2 3 4 3
输出
1 5 2 2 3
备注:
1 ≤ N、Q ≤ 52501,1 ≤ M ≤ 20,1 ≤ u[i]、v[i]、x、y ≤ N,1 ≤ d[i]、w[i] ≤ 2^(30)
const int MAX=53000;
int cnt;
int n,m;
int head[MAX<<1];
int vis[MAX];
ll dis[MAX];
ll sum[MAX];
ll con[25][MAX];
struct Edge{
int to,next,w;
}edge[MAX<<1]; //存图
void init(){
mms(head,-1);
mms(con,INF);
for(int i=0;i<MAX;i++){
edge[i].next=-1;
}
cnt=0;
}
void add(int u,int v,int w){ //前向星
edge[cnt].to=v;
edge[cnt].w=w;
edge[cnt].next=head[u];
head[u]=cnt++;
}
void spfa(int k,int s){
mms(vis,0);
mms(dis,INF);
queue<int>q;
q.push(s);
dis[s]=0;
while (!q.empty()) {
int u=q.front();
q.pop();
for(int i=head[u];~i;i=edge[i].next){
int v=edge[i].to;
int w=edge[i].w;
if(dis[v]>dis[u]+w){
dis[v]=dis[u]+w;
q.push(v);
}
}
}
for(int i=1;i<=n;i++){ //
con[k][i]=dis[i];
}
}
int main(){
cin>>n>>m;
init();
ll d;
sum[1]=0;
for(int i=1;i<=n-1;i++){
cin>>d;
add(i,i+1,d);
add(i+1,i,d);
sum[i+1]=sum[i]+d;
}
cin>>d;
add(1,n,d);
add(n,1,d);
sum[0]=sum[n]+d;
for(int i=1;i<=m;i++){
int u,v,w;
cin>>u>>v>>w;
add(u,v,w);
add(v,u,w);
spfa(i,u);
spfa(i,v);
}
int q;
cin>>q;
int ans=INF;
while (q--) {
int u,v;
cin>>u>>v;
ans=abs(sum[u]-sum[v]);//顺
ans=min(ans,sum[0]-ans);//逆
for(int i=1;i<=m;i++){
ans=min(ans,con[i][v]+con[i][u]); //比较
}
cout<<ans<<endl;
}
}