想日这道题都得有一年了……今天发现yh都把这题日了,我才终于来日他
这题题解网上都烂大街了,我也懒得写……不过这题其实不需要线段树的
先任意搞一条S到T的最短路,然后对于不在最短路上的一条边,x->y,假设我们要强制经过这条边的话,最优情况一定是S走最短路到x,再x->y,再y走最短路到T
那么S走最短路到x一定是先走一段S到T的最短路,然后离开最短路,y走到T一定是先走一段别的路,然后进入S到T的最短路
那么这个路径就可以用来更新最短路上一段区间的答案
那么我们用一个multiset扫一遍就行了,不过这么搞常数好像比线段树大,我不加读入优化就TLE了-_-
#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<ctime>
#include<cmath>
#include<algorithm>
#include<iomanip>
#include<bitset>
#include<set>
#include<map>
#include<vector>
#include<stack>
#include<queue>
using namespace std;
#define MAXN 200010
#define MAXM 1010
#define INF 1000000000
#define MOD 1000000007
#define eps 1e-8
#define ll long long
char xch,xB[1<<15],*xS=xB,*xTT=xB;
#define getc() (xS==xTT&&(xTT=(xS=xB)+fread(xB,1,1<<15,stdin),xS==xTT)?0:*xS++)
inline int read()
{
int x=0,f=1;char ch=getc();
while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getc();}
while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getc();}
return x*f;
}
struct data{
int x;
ll v;
data(){
}
data(int _x,ll _v){
x=_x;
v=_v;
}
friend bool operator <(data x,data y){
return x.v>y.v;
}
};
struct vec{
int to;
int fro;
int v;
};
vec mp[MAXN*2];
int tai[MAXN],cnt;
priority_queue<data>q;
int n,m,Q;
map<pair<int,int>,ll>h;
map<pair<int,int>,bool>arr;
bool vis[MAXN];
int rds[MAXN],rdt[MAXN];
ll diss[MAXN],dist[MAXN];
bool ar[MAXN];
bool fds[MAXN],fdt[MAXN];
vector<ll>irs[MAXN],drs[MAXN];
multiset<ll>s;
int S,T;
int v1[MAXN],v2[MAXN],v[MAXN];
int fvs[MAXN],fvt[MAXN];
int dep[MAXN];
inline void be(int x,int y,int z){
mp[++cnt].to=y;
mp[cnt].fro=tai[x];
tai[x]=cnt;
mp[cnt].v=z;
}
inline void bde(int x,int y,int z){
be(x,y,z);
be(y,x,z);
}
int find(int x,int *rd,bool *fd,int *fv){
if(fd[x]){
return fv[x];
}
fd[x]=1;
if(ar[x]){
return fv[x]=x;
}
return fv[x]=find(rd[x],rd,fd,fv);
}
void dijkstra(int s,ll *dis,int *rd){
int i,x,y;
memset(vis,0,sizeof(vis));
memset(dis,0x3f,sizeof(dis));
for(i=1;i<=n;i++){
vis[i]=0;
dis[i]=1000000000000000000ll;
}
q.push(data(s,dis[s]=0));
while(!q.empty()){
x=q.top().x;
q.pop();
if(vis[x]){
continue ;
}
vis[x]=1;
for(i=tai[x];i;i=mp[i].fro){
y=mp[i].to;
if(dis[y]>dis[x]+mp[i].v){
rd[y]=x;
q.push(data(y,dis[y]=dis[x]+mp[i].v));
}
}
}
}
int main(){
int i,x,y,z;
n=read();
m=read();
for(i=1;i<=m;i++){
v1[i]=read();
v2[i]=read();
v[i]=read();
bde(v1[i],v2[i],v[i]);
}
S=read();
T=read();
dijkstra(S,diss,rds);
dijkstra(T,dist,rdt);
ar[0]=1;
if(vis[S]){
x=T;
dep[T]=1;
while(x!=S){
ar[x]=1;
arr[make_pair(x,rds[x])]=1;
arr[make_pair(rds[x],x)]=1;
dep[rds[x]]=dep[x]+1;
x=rds[x];
}
ar[S]=1;
for(i=1;i<=m;i++){
if(arr[make_pair(v1[i],v2[i])]){
continue ;
}
x=find(v1[i],rds,fds,fvs);
y=find(v2[i],rdt,fdt,fvt);
if(x&&y&&dep[y]<dep[x]){
irs[y].push_back(diss[v1[i]]+dist[v2[i]]+v[i]);
drs[x].push_back(diss[v1[i]]+dist[v2[i]]+v[i]);
}
x=find(v2[i],rds,fds,fvs);
y=find(v1[i],rdt,fdt,fvt);
if(x&&y&&dep[y]<dep[x]){
irs[y].push_back(diss[v2[i]]+dist[v1[i]]+v[i]);
drs[x].push_back(diss[v2[i]]+dist[v1[i]]+v[i]);
}
}
for(x=T;x!=S;x=rds[x]){
for(i=0;i<irs[x].size();i++){
s.insert(irs[x][i]);
}
for(i=0;i<drs[x].size();i++){
s.erase(s.find(drs[x][i]));
}
if(s.size()){
h[make_pair(x,rds[x])]=*s.begin();
h[make_pair(rds[x],x)]=*s.begin();
}else{
h[make_pair(x,rds[x])]=-1;
h[make_pair(rds[x],x)]=-1;
}
}
}
Q=read();
while(Q--){
x=read();
y=read();
if(!vis[S]){
printf("Infinity\n");
continue ;
}
if(!arr[make_pair(x,y)]){
printf("%lld\n",diss[T]);
}else if(h[make_pair(x,y)]==-1){
printf("Infinity\n");
}else{
printf("%lld\n",h[make_pair(x,y)]);
}
}
return 0;
}
/*
6 7
1 2 1
2 3 1
3 4 2
4 5 1
5 6 1
1 3 3
4 6 3
1 6
4
1 2
1 3
4 3
6 5
*/